Hallo Habr! Ich präsentiere Ihnen die Übersetzung des Artikels 
„Was tun, wenn„ dies “den Kontext verliert ? “ Von 
Cristi Salcescu .
Der beste Weg, um zu vermeiden, dass 
dieser Kontext verloren geht, besteht darin, ihn nicht zu verwenden. Dies ist jedoch nicht immer möglich. Zum Beispiel arbeiten wir mit dem Code oder der Bibliothek einer anderen Person, die 
dies verwendet .
Objektliteral, Konstruktorfunktion, Klassenobjektkonstruktor im Prototypsystem. Dieser Pseudoparameter 
wird im Prototyping-System verwendet, um Zugriff auf die Eigenschaften des Objekts zu erhalten. 
Schauen wir uns einige Fälle an.
Verschachtelte Funktionen
Dadurch geht die Kontextreferenz in verschachtelten Funktionen verloren.
class Service { constructor(){ this.numbers = [1,2,3]; this.token = "token"; } doSomething(){ setTimeout(function doAnotherThing(){ this.numbers.forEach(function log(number){  
Die Methode 
doSomething () verfügt über zwei verschachtelte Funktionen: 
doAnotherthing () und 
log () . Beim Aufruf von 
service.doSomething () geht die Kontextreferenz in der verschachtelten Funktion verloren.
bind ()
Eine Möglichkeit, das Problem zu lösen, ist die 
bind () -Methode. Sehen Sie sich den folgenden Code an:
 doSomething(){ setTimeout(function doAnotherThing(){ this.numbers.forEach(function log(number){ console.log(number); console.log(this.token); }.bind(this)); }.bind(this), 100); } 
bind () erstellt eine neue Version der Funktion, die beim Aufruf bereits einen bestimmten Wert 
davon hat .
Die Funktion doAnotherThing () {/*...*/}.bind(this) erstellt eine Version der Funktion 
doAnotherThing () , die den Wert von 
doSomething () übernimmt.
das / selbst
Eine andere Möglichkeit besteht darin, die neue Variable 
that / self zu deklarieren und zu verwenden, in der 
dieser Wert aus der Methode 
doSomething () gespeichert wird.
 doSomething(){ let that = this; setTimeout(function doAnotherThing(){ that.numbers.forEach(function log(number){ console.log(number); console.log(that.token); }); }, 100); } 
Wir müssen 
let that = this in allen Methoden deklarieren 
, die dies in verschachtelten Funktionen verwenden.
Pfeilfunktionen
Die Pfeilfunktion gibt uns eine andere Möglichkeit, dieses Problem zu lösen.
 doSomething(){ setTimeout(() => { this.numbers.forEach(number => { console.log(number); console.log(this.token); }); }, 100); } 
Pfeilfunktionen erstellen hierfür keinen eigenen Kontext, sondern verwenden 
diesen Wert des umgebenden Kontexts. Im obigen Beispiel wird der Wert 
dieser Funktion 
der übergeordneten Funktion verwendet.
Der Nachteil dieser Methode ist, dass wir den Namen der Pfeilfunktion nicht angeben können. Der Name der Funktion spielt eine wichtige Rolle, da er die Lesbarkeit des Codes erhöht und seinen Zweck beschreibt.
Unten finden Sie denselben Code mit einer Funktion, die in Form eines Variablennamens ausgedrückt wird:
 doSomething(){ let log = number => { console.log(number); console.log(this.token); } let doAnotherThing = () => { this.numbers.forEach(log); } setTimeout(doAnotherThing, 100); } 
Rückruffunktionen (Methode als Rückruf)
Dies verliert die Kontextreferenz, wenn die Methode als Rückruffunktion verwendet wird. Schauen wir uns die folgende Klasse an:
 class Service { constructor(){ this.token = "token"; } doSomething(){ console.log(this.token); 
Schauen wir uns Situationen an, in denen die Methode 
service.doSomething () als Rückruffunktion verwendet wird.
 
In allen oben genannten Fällen verliert dies die Kontextverknüpfung.
bind ()
Wir können 
bind () verwenden , um dieses Problem zu lösen. Unten ist der Code für diese Option:
 
Pfeilfunktion
Eine andere Möglichkeit besteht darin, eine Pfeilfunktion zu erstellen, die 
service.doSomething () aufruft.
 
Komponenten reagieren
In Komponenten verliert 
dies die Kontextreferenz, wenn Methoden als Rückrufe für Ereignisse verwendet werden.
 class TodoAddForm extends React.Component { constructor(){ super(); this.todos = []; } componentWillMount() { this.setState({desc: ""}); } add(){ let todo = {desc: this.state.desc};  
Als Lösung können wir im Konstruktor neue Funktionen erstellen, die 
bind (this) verwenden .
 constructor(){ super(); this.todos = []; this.handleChange = this.handleChange.bind(this); this.add = this.add.bind(this); } 
Verwenden Sie nicht "dies"
Nein 
das - keine Probleme mit Kontextverlust. Objekte können mit 
Factory-Funktionen erstellt werden. Schauen Sie sich dieses Beispiel an:
 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 }); } 
Der Kontext bleibt erhalten, wenn Sie die Methode als Rückruf verwenden.
 let service = Service(); service.doSomething();  
Fazit
Dies verliert in verschiedenen Situationen den Kontextbezug.
bind () , die 
diese / self- Variablen- und Pfeilfunktionen verwenden, sind Möglichkeiten, Kontextprobleme zu lösen.
Factory-Funktionen ermöglichen das Erstellen von Objekten ohne 
diese .