In TypeScript ist der Typ von this für Methoden innerhalb einer Klasse standardmäßig die aktuelle Instanz der Klasse. Wenn Methoden jedoch als Arrow-Funktionen definiert werden, wird der Kontext von this an den Zeitpunkt der Deklaration gebunden, nicht an den Zeitpunkt des Aufrufs.
Normale Methode:
class Counter { value = 0; increment() { this.value++; } }
Arrow-Funktion:
class Counter { value = 0; increment = () => { this.value++; } }
Finesse:
this, wenn sie zum Beispiel als Callback übergeben werden (z. B. in Event-Listener).this in der Methodensignatur für zusätzliche Überprüfungen explizit angeben:class Foo { bar(this: Foo) { // ... } }
Was ist der Unterschied zwischen
increment()undincrement = () => {}in der Klasse? Wie wirkt sich das auf den Kontext von this aus, wenn sie als Callback verwendet werden?
Falsche Antwort:
Richtige Antwort:
this für eine normale Methode wird zum Zeitpunkt des Aufrufs bestimmt. Wenn man die Methode als Funktion übergibt: setTimeout(counter.increment, 0), wird this zu undefined (im strengen Modus) oder window (im nicht-strengen Modus), während die Arrow-Funktion ihr Umfeld behält:class Demo { value = 1; inc() { console.log(this.value); } incArrow = () => { console.log(this.value); } } const d = new Demo(); setTimeout(d.inc, 0); // undefined oder Fehler setTimeout(d.incArrow, 0); // 1
Geschichte
In einem Projekt mit reaktiven Frameworks wurden die Methoden der Klasse direkt als Callbacks ohne explizites Bind übergeben. Infolgedessen wurde this undefined und die Anwendung brach mit einem Fehler beim Zugriff auf this-Eigenschaften zusammen. Das Problem wurde gelöst, indem die Methoden in Arrow-Funktionen umgeschrieben oder explizit gebunden wurden.
Geschichte
Ein Entwickler gab den Typ von this in der Methode explizit an, vergaß jedoch die Typisierung innerhalb der Arrow-Funktion innerhalb dieser Methode. Dies führte dazu, dass this im verschachtelten Callback nicht auf die Instanz der Klasse verwies, sondern auf window. Das Team stieß auf einen Zustandverlust und musste die Ereignisarchitektur überarbeiten.
Geschichte
Eine große UI-Komponente verlangsamte die Anwendung, weil alle Methoden als Arrow-Funktion in der Klasse beschrieben waren (new Counter().increment = ...), was neue Funktionskopien für jede Instanz erzeugte, anstatt eine einzige Definition im Prototyp zu haben, wie es bei einer normalen Methode der Fall wäre. Dadurch erhöhte sich der Speicherverbrauch, und eine Optimierung war nötig.