Il existe trois principales façons de traiter this
dans les rappels :
1. Créez une variable à portée lexicale, comme vous le faites actuellement
Les deux noms les plus courants pour cette nouvelle variable sont that
et self
. Personnellement, je préfère utiliser that
car les navigateurs ont une propriété globale de la fenêtre appelée self et mon linter se plaint si je l'ombre.
function edit(req, res) {
var that = this,
db.User.findById('ABCD', function(err, user){
that.foo(user);
});
};
Un avantage de cette approche est que une fois que le code est converti pour utiliser that
, vous pouvez ajouter autant de rappels internes que vous le souhaitez et ils fonctionneront tous parfaitement en raison de la portée lexicale. Un autre avantage est que c'est très simple et cela fonctionnera même sur d'anciens navigateurs.
2. Utilisez la méthode .bind().
Les fonctions Javascript ont une méthode .bind()
qui vous permet de créer une version d'elles avec un this
fixe.
function edit(req, res) {
db.User.findById('ABCD', (function(err, user){
this.foo(user);
}).bind(this));
};
En ce qui concerne la gestion de this
, la méthode bind est particulièrement utile pour les rappels ponctuels où l'ajout d'une fonction d'enrobage serait plus verbeux :
setTimeout(this.someMethod.bind(this), 500);
var that = this;
setTimeout(function(){ that.doSomething() }, 500);
Le principal inconvénient de bind
est que si vous avez des rappels imbriqués, vous devez également appeler bind
sur eux. De plus, IE <= 8 et certains autres anciens navigateurs, n'implémentent pas nativement la méthode bind
donc vous pourriez avoir besoin d'utiliser une sorte de bibliothèque de shim si vous devez toujours les prendre en charge.
3. Si vous avez besoin d'un contrôle plus fin de la portée des fonctions ou des arguments, revenez à .call() et .apply()
Les façons plus primitives de contrôler les paramètres des fonctions en Javascript, y compris le this
, sont les méthodes .call()
et .apply()
. Elles vous permettent d'appeler une fonction avec n'importe quel objet comme leur this
et n'importe quelles valeurs comme ses paramètres. apply
est particulièrement utile pour implémenter des fonctions variadiques, car elle reçoit la liste d'arguments sous forme d'array.
Par exemple, voici une version de bind qui reçoit la méthode à lier sous forme de chaîne. Cela nous permet d'écrire le this
une seule fois au lieu de deux.
function myBind(obj, funcname){
return function(/**/){
return obj[funcname].apply(obj, arguments);
};
}
setTimeout(myBind(this, 'someMethod'), 500);