In TypeScript is het type this binnen klasmethoden standaard de huidige instantie van de klasse. Echter, als methoden gedefinieerd worden met pijl functies, wordt de context van this gebonden op het moment van declaratie, en niet op het moment van aanroep.
Gewone methode:
class Counter { value = 0; increment() { this.value++; } }
Pijl functie:
class Counter { value = 0; increment = () => { this.value++; } }
Fijnere punten:
this wanneer ze als callbacks worden doorgegeven (bijvoorbeeld in event listeners).this in de handtekening van de methode aangeven voor extra controle:class Foo { bar(this: Foo) { // ... } }
Wat is het verschil tussen
increment()enincrement = () => {}in de klasse? Hoe beïnvloedt dit de context van this bij gebruik als callback?
Onjuist antwoord:
Juist antwoord:
this bepaald op het moment van aanroep. Als je de methode als functie doorgeeft: setTimeout(counter.increment, 0), dan wordt this undefined (in strict mode) of window (in non-strict mode), terwijl de pijl functie haar omgeving behoudt:class Demo { value = 1; inc() { console.log(this.value); } incArrow = () => { console.log(this.value); } } const d = new Demo(); setTimeout(d.inc, 0); // undefined of fout setTimeout(d.incArrow, 0); // 1
Verhaal
In een project met reactieve frameworks werden de klassmethoden rechtstreeks als callbacks doorgegeven zonder expliciete bind. Dit resulteerde in this dat undefined werd, en de applicatie crashte met een fout bij toegang tot this-eigenschappen. Het probleem werd opgelost door de methoden te herschrijven naar pijl functies of door expliciete bind toe te passen.
Verhaal
Een ontwikkelaar gaf expliciet het type this aan in de methode, maar vergat de typificatie binnen de pijl functie in deze methode. Dit resulteerde erin dat this binnen de ingesloten callback niet naar de klasse instantie wees, maar naar window. Het team kwam een state leak tegen en moest de evenementarchitectuur herschrijven.
Verhaal
Een grote UI-component vertraagde de applicatie omdat alle methoden als pijl velden van de klasse waren gedefinieerd (new Counter().increment = ...), wat nieuwe functie kopieën creëerde voor elke instantie, in plaats van één definitie op het prototype te hebben zoals bij een gewone methode. Dit resulteerde in een verhoogd geheugengebruik en er was optimalisatie nodig.