Krótszy sposób zapisu funkcji
Funkcje strzałkowe to zwięźlejsza składnia JavaScript do definiowania funkcji. Pojawiły się w ES2015 i dziś są domyślnym stylem dla małych funkcji pisanych w miejscu użycia, zwłaszcza callbacków przekazywanych do metod tablic, handlerów obietnic i event listenerów.
Schemat jest taki: parametry, potem =>, potem ciało funkcji.
Wynik ten sam co w klasycznej formie:
const add = function (a, b) {
return a + b;
};
Mniej pisania to miła sprawa, ale prawdziwe powody, dla których warto znać funkcje strzałkowe, to niejawny return i sposób, w jaki traktują this. O obu za chwilę.
Niejawny return
Jeśli ciało funkcji to jedno wyrażenie, możesz pominąć nawiasy klamrowe i return. Wartość wyrażenia zostanie zwrócona automatycznie:
Tu funkcje strzałkowe błyszczą: jednolinijkowe przekształcenia czyta się jak wzory matematyczne:
Gdy tylko potrzebujesz więcej niż jednej instrukcji, wracasz do nawiasów klamrowych i jawnego return:
Zapomniany return wewnątrz nawiasów klamrowych to najczęstszy błąd przy funkcjach strzałkowych. x => { x * 2 } zwraca undefined: nawiasy zamieniają ciało w blok, a wyrażenie w środku zostaje wyrzucone.
Nawiasy wokół parametrów
Przy dokładnie jednym parametrze nawiasy są opcjonalne:
Przy zerze, dwóch lub większej liczbie parametrów są potrzebne:
Niektóre zespoły dla spójności wolą zawsze stawiać nawiasy. Oba style są w porządku: wybierz jeden i się go trzymaj.
Zwracanie literału obiektu
Oto pułapka. Jeśli spróbujesz niejawnie zwrócić obiekt, nawiasy klamrowe wyglądają jak ciało funkcji:
To wypisuje undefined. JavaScript czyta { name: name } jako blok z instrukcją z etykietą, a nie jako literał obiektu. Owiń obiekt w nawiasy okrągłe, żeby wymusić wyrażenie:
Rozwiązaniem są () wokół { ... }. Zapamiętaj to: trafisz na ten problem w pierwszym tygodniu pisania funkcji strzałkowych.
Leksykalne this
Prawdziwym powodem istnienia funkcji strzałkowych nie jest krótsza składnia. Chodzi o to, że nie mają własnego this. Dziedziczą je z otaczającego zakresu.
Żeby zobaczyć, dlaczego to ważne, weźmy zwykłą funkcję użytą jako callback:
Wewnątrz function () { ... } przekazanej do setInterval this nie jest counter. Zwykłe funkcje dostają własne this zależnie od tego, jak zostały wywołane, a setInterval wywołuje callback z this równym undefined (w trybie ścisłym) albo obiektowi globalnemu.
Funkcja strzałkowa zachowuje this otaczającej metody:
Wewnątrz funkcji strzałkowej this nadal wskazuje counter, bo strzałka nie wprowadza własnego this. Przed funkcjami strzałkowymi obchodzono to przez const self = this; albo .bind(this). Te wzorce nadal działają, ale dziś rzadko są potrzebne.
Czego nie mają funkcje strzałkowe
Reguła leksykalnego this to część szerszego wzorca: funkcje strzałkowe pomijają kilka rzeczy, które mają zwykłe funkcje.
- Brak własnego
this: dziedziczone z otaczającego zakresu. - Brak obiektu
arguments: zamiast niego użyj parametrów rest (...args). - Brak
new: funkcji strzałkowej nie użyjesz jako konstruktora. - Brak właściwości
prototype: wynika to z brakunew.
...args daje tę samą możliwość "przyjmij dowolną liczbę argumentów" co arguments, z tym bonusem, że to prawdziwa tablica. Wywołanie new Greeter(...) rzuca błąd, bo funkcje strzałkowe nie są konstruktorami.
Kiedy nie używać funkcji strzałkowej
Funkcje strzałkowe to domyślny wybór dla callbacków, ale w kilku miejscach są złym wyborem:
Metody obiektu zdefiniowane składnią strzałkową nie mają this powiązanego z obiektem: dziedziczą je z miejsca, w którym zapisano literał obiektu (zwykle z zakresu modułu albo globalnego). Do metod używaj skróconej składni metod (greet() { ... }).
Tak samo jest z metodami prototypu klasy, metodami obsługi zdarzeń, w których this ma wskazywać element, i każdą funkcją, którą zamierzasz wywołać z new. Tam właściwym narzędziem jest zwykła function.
Szybka zasada praktyczna
- Krótki callback, jedno wyrażenie? Funkcja strzałkowa.
thisma pozostać powiązane z zewnętrznym zakresem? Funkcja strzałkowa.- Definiujesz metodę obiektu albo prototypu klasy? Zwykła funkcja (albo skrócona metoda).
- Piszesz konstruktor? Zwykła funkcja, a jeszcze lepiej
class.
W każdym prawdziwym projekcie JavaScript zobaczysz oba style. Wyczucie, który pasuje, przychodzi po kilku tygodniach czytania cudzego kodu, a potem wybór staje się automatyczny.
Dalej: parametry i wartości domyślne
Funkcje strzałkowe i zwykłe funkcje mają te same możliwości parametrów: wartości domyślne, parametry rest, destrukturyzację argumentów i nie tylko. To temat następnej strony i dotyczy każdej formy funkcji, o której była dotąd mowa.
Najczęściej zadawane pytania
Czym jest funkcja strzałkowa w JavaScript?
Funkcja strzałkowa (arrow function) to krótszy sposób zapisu funkcji ze składnią =>. const add = (a, b) => a + b; to funkcja strzałkowa, która przyjmuje dwa argumenty i zwraca ich sumę. Poza zwięźlejszą składnią funkcje strzałkowe nie wiążą własnego this, arguments ani super: dziedziczą je z otaczającego zakresu.
Czym różnią się funkcje strzałkowe od zwykłych funkcji?
Zwykłe funkcje zadeklarowane przez function mają własne this, własny obiekt arguments i mogą służyć jako konstruktory z new. Funkcje strzałkowe nie mają nic z tego: dziedziczą this z miejsca, w którym zostały zdefiniowane. Nie podlegają też hoistingowi tak jak deklaracje funkcji.
Kiedy używać funkcji strzałkowej?
Sięgaj po funkcje strzałkowe przy krótkich callbackach (arr.map(x => x * 2)) i wszędzie tam, gdzie this ma pozostać powiązane z otaczającym zakresem, na przykład w metodzie klasy, która przekazuje handler do setTimeout albo do event listenera. Zwykłej function używaj do metod obiektów, konstruktorów i samodzielnych funkcji najwyższego poziomu.