programowanieFrontend developer

Jak działa mechanizm typizacji this w metodach klas TypeScript przy użyciu zwykłych i strzałkowych funkcji? Opisuj pułapki i najlepsze praktyki.

Zdaj rozmowy kwalifikacyjne z asystentem AI Hintsage

Odpowiedź.

W TypeScript dla metod w klasie typ this domyślnie to bieżąca instancja klasy. Jednak, jeśli definiujemy metody za pomocą funkcji strzałkowych, kontekst this będzie związany z momentem deklaracji, a nie wywołania.

Zwykła metoda:

class Counter { value = 0; increment() { this.value++; } }

Funkcja strzałkowa:

class Counter { value = 0; increment = () => { this.value++; } }

Szczegóły:

  • Zwykłe metody tracą kontekst this podczas przekazywania ich jako callbacki (na przykład do event listenerów).
  • Strzałkowe zachowują kontekst zadeklarowanej klasy, ale nie są widoczne w prototypie i są tworzone dla każdej instancji.
  • Można jawnie określić typ this w sygnaturze metody dla dodatkowej kontroli:
class Foo { bar(this: Foo) { // ... } }

Pytanie z haczykiem.

Czym różni się increment() i increment = () => {} w klasie? Jak wpływa to na kontekst this przy użyciu jako callback?

Błędna odpowiedź:

  • "W polu klasy i w metodzie nie ma różnicy, TypeScript sam wszystko rozumie."

Poprawna odpowiedź:

  • W zwykłej metodzie kontekst this jest określany w momencie wywołania. Jeśli przekażesz metodę jako funkcję: setTimeout(counter.increment, 0), to this stanie się undefined (w trybie surowym) lub window (w trybie niesurowym), podczas gdy funkcja strzałkowa zachowa swoje otoczenie:
class Demo { value = 1; inc() { console.log(this.value); } incArrow = () => { console.log(this.value); } } const d = new Demo(); setTimeout(d.inc, 0); // undefined lub błąd setTimeout(d.incArrow, 0); // 1

Przykłady rzeczywistych błędów z powodu braku wiedzy o szczegółach tematu.


Historia

W projekcie z reaktywnymi frameworkami metody klasy były przekazywane bezpośrednio jako callbacki bez jawnego bind. W rezultacie this stawał się undefined, a aplikacja wypadała z błędem podczas uzyskiwania dostępu do właściwości this. Problem został rozwiązany przepisaniem metod na strzałkowe lub jawne bind.


Historia

Programista jawnie określił typ this w metodzie, ale zapomniał o typizacji wewnątrz funkcji strzałkowej w tej metodzie. Okazało się, że this w wewnętrznym callbacku wskazywał nie na instancję klasy, a na window. Zespół napotkał problem z wyciekiem stanu, musiał przerabiać architekturę zdarzeń.


Historia

Duży komponent UI spowalniał aplikację, ponieważ wszystkie metody były opisane jako strzałkowe pola klasy (new Counter().increment = ...), co tworzyło nowe kopie funkcji dla każdej instancji, a nie jedno określenie w prototypie, jak to ma miejsce w przypadku zwykłej metody. W rezultacie zwiększyło się zużycie pamięci, co wymagało optymalizacji.