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:
this podczas przekazywania ich jako callbacki (na przykład do event listenerów).this w sygnaturze metody dla dodatkowej kontroli:class Foo { bar(this: Foo) { // ... } }
Czym różni się
increment()iincrement = () => {}w klasie? Jak wpływa to na kontekst this przy użyciu jako callback?
Błędna odpowiedź:
Poprawna odpowiedź:
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
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.