ProgrammatieFrontend ontwikkelaar

Hoe is het typing mechanisme van this in TypeScript class methoden geregeld bij gebruik van gewone en pijl functies? Beschrijf de haken en ogen en best practices.

Slaag voor sollicitatiegesprekken met de Hintsage AI-assistent

Antwoord.

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:

  • Gewone methoden verliezen de context van this wanneer ze als callbacks worden doorgegeven (bijvoorbeeld in event listeners).
  • Pijl functies behouden de context van de gedefinieerde klasse, maar zijn niet zichtbaar in het prototype en worden voor elke instantie gemaakt.
  • Je kunt expliciet het type this in de handtekening van de methode aangeven voor extra controle:
class Foo { bar(this: Foo) { // ... } }

Vraag met een valstrik.

Wat is het verschil tussen increment() en increment = () => {} in de klasse? Hoe beïnvloedt dit de context van this bij gebruik als callback?

Onjuist antwoord:

  • "Er is geen verschil tussen het veld van de klasse en de methode, TypeScript begrijpt het zelf."

Juist antwoord:

  • Bij een gewone methode wordt de context van 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

Voorbeelden van echte fouten door onbekendheid met de subtiliteiten van het onderwerp.


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.