Bonjour, Habr! Je vous présente la traduction de l'article 
«Que faire quand« cela »perd le contexte» de 
Cristi Salcescu .
La meilleure façon d'éviter de perdre 
ce contexte est de ne pas l'utiliser. Mais ce n'est pas toujours possible. Par exemple, nous travaillons avec le code ou la bibliothèque d'une autre personne qui l'utilise.
Littéral d'objet, fonction constructeur, constructeur d'objet de classe dans le système prototype. Ce pseudo- 
paramètre est utilisé dans le système de prototypage afin de donner accès aux propriétés de l'objet. 
Regardons quelques cas.
Fonctions imbriquées
cela perd la référence de contexte à l'intérieur des fonctions imbriquées.
class Service { constructor(){ this.numbers = [1,2,3]; this.token = "token"; } doSomething(){ setTimeout(function doAnotherThing(){ this.numbers.forEach(function log(number){  
La méthode 
doSomething () a deux fonctions imbriquées: 
doAnotherthing () et 
log () . Lorsque vous appelez 
service.doSomething () , 
cela perd la référence de contexte dans la fonction imbriquée.
bind ()
Une façon de résoudre le problème est d' 
utiliser la méthode 
bind () . Jetez un œil au code suivant:
 doSomething(){ setTimeout(function doAnotherThing(){ this.numbers.forEach(function log(number){ console.log(number); console.log(this.token); }.bind(this)); }.bind(this), 100); } 
bind () crée une nouvelle version de la fonction qui, lorsqu'elle est appelée, a déjà une certaine valeur.
La fonction doAnotherThing () {/*...*/}.bind(this) crée une version de la fonction 
doAnotherThing () , qui prend la valeur de 
ceci de 
doSomething () .
ça / moi
Une autre option consiste à déclarer et à utiliser la nouvelle variable 
that / self , qui stockera la valeur 
this de la méthode 
doSomething () .
 doSomething(){ let that = this; setTimeout(function doAnotherThing(){ that.numbers.forEach(function log(number){ console.log(number); console.log(that.token); }); }, 100); } 
Nous devons déclarer 
let that = this dans toutes les méthodes utilisant 
this dans des fonctions imbriquées.
Fonctions fléchées
La fonction flèche nous donne une autre façon de résoudre ce problème.
 doSomething(){ setTimeout(() => { this.numbers.forEach(number => { console.log(number); console.log(this.token); }); }, 100); } 
Les fonctions fléchées ne créent pas leur propre contexte pour 
cela , mais utilisent plutôt la valeur 
this du contexte environnant. Dans l'exemple ci-dessus, il utilise la valeur de 
this de la fonction parent.
L'inconvénient de cette méthode est que nous ne pouvons pas spécifier le nom de la fonction flèche. Le nom de la fonction joue un rôle important, car il augmente la lisibilité du code et décrit son objectif.
Voici le même code avec une fonction exprimée en termes de nom de variable:
 doSomething(){ let log = number => { console.log(number); console.log(this.token); } let doAnotherThing = () => { this.numbers.forEach(log); } setTimeout(doAnotherThing, 100); } 
Fonctions de rappel (méthode comme rappel)
cela perd la référence de contexte lors de l'utilisation de la méthode comme fonction de rappel. Regardons la classe suivante:
 class Service { constructor(){ this.token = "token"; } doSomething(){ console.log(this.token); 
Examinons les situations dans lesquelles la méthode 
service.doSomething () est utilisée comme fonction de rappel.
 
Dans tous les cas ci-dessus, 
cela perd le lien de contexte.
bind ()
Nous pouvons utiliser 
bind () pour résoudre ce problème. Voici le code de cette option:
 
Fonction flèche
Une autre façon consiste à créer une fonction de flèche qui appelle 
service.doSomething () .
 
Composants React
Dans les composants, 
cela perd la référence de contexte lorsque les méthodes sont utilisées comme rappels pour les événements.
 class TodoAddForm extends React.Component { constructor(){ super(); this.todos = []; } componentWillMount() { this.setState({desc: ""}); } add(){ let todo = {desc: this.state.desc};  
Comme solution, nous pouvons créer de nouvelles fonctions dans le constructeur qui utiliseront 
bind (this) .
 constructor(){ super(); this.todos = []; this.handleChange = this.handleChange.bind(this); this.add = this.add.bind(this); } 
N'utilisez pas «this»
Non, pas de problème de perte de contexte. Les objets peuvent être créés à l'aide 
des fonctions d'usine . Jetez un œil à cet exemple:
 function Service() { let numbers = [1,2,3]; let token = "token"; function doSomething(){ setTimeout(function doAnotherThing(){ numbers.forEach(function log(number){ console.log(number); console.log(token); }); }, 100); } return Object.freeze({ doSomething }); } 
Le contexte reste si vous utilisez la méthode comme rappel.
 let service = Service(); service.doSomething();  
Conclusion
cela perd la référence de contexte dans diverses situations.
bind () , en utilisant 
cette variable 
/ self et les fonctions flèches sont des moyens de résoudre les problèmes de contexte.
Les fonctions d'usine permettent de créer des objets sans l'utiliser.