Nasza strona używa cookies. Korzystając ze strony, wyrażasz zgodę na używanie cookies, zgodnie z aktualnymi ustawieniami przeglądarki. Rozumiem

Kiedy nie warto używać funkcji strzałkowych w JavaScript

Dowiedz się, w jakich czterech przypadkach używanie funkcji strzałkowych w JavaScript przyniesie więcej minusów niż plusów.
Kiedy nie warto używać funkcji strzałkowych w JavaScript

Funkcje strzałkowe wprowadzone jako część ECMAScript 6 poszły świat jako viral i nie ma co się temu dziwić. Nowa składnia deklarowania funkcji jest świetna! Oszczędza czas i poprawia przejrzystość w wielu sytuacjach, usuwając wszystkie rozpraszające i niepotrzebne fragmenty, które zwykle pojawiały się przy deklarowaniu funkcji JS.

Weźmy przykład zwykłą deklarację funkcji oraz tę samą deklarację, tylko w formie funkcji strzałkowej.

function welcome() {
  return "Welcome!"
}


teraz funkcje strzałkowe z ES6:

const welcome = () => "Welcome!"


Nie przekonuje Cię to wystarczająco? Spójrzmy na inny przykład:

const f = list.map(function(item) { return item; })


kontra

const f = list.map((item) => item)


Czy to nie piękne?

Trzeba jednak uważać, ponieważ różnice między dwiema deklaracjami to nie tylko składnia i nie zawsze można stosować to rozwiązanie. Oto przykłady sytuacji, w których używanie funkcji strzałkowych nie jest dobrym pomysłem.


Metody obiektu

Spójrz na następujący przykład:

const article = {
  claps: 0,
  clap: () => {
    this.claps++;
  }
}


W tym przykładzie intuicyjnie można by przypuszczać, że za każdym razem, gdy wywołujemy article.clap(), to atrybut article.claps zwiększy się o jeden (z 0 do 1). Tak jednak nie jest - wartość claps niestety pozostaje taka sama.

Sprawdźmy zatem, dlaczego to tak nie działa. Problem, jak zwykle, dotyczy this oraz zasięgu.

Jak wynika z dokumentacji MDN:

Wyrażenie funkcji strzałkowej jest kompaktową pod względem składniowym alternatywą dla zwykłego wyrażenia definującego funkcję, chociaż bez powiązań ze słowami kluczowymi this, arguments, super lub new.target. Wyrażenia funkcji strzałkowych nie nadają się do stosowania ich jako metody i nie mogą być używane jako konstruktory.

co oznacza, że w naszym przypadku zasięgiem byłby obiektem window. Wywołanie metody clap() spowodowałoby po prostu próbę zwiększenia wartości claps w obiekcie window.

Jeśli jednak zamiast tego użyjemy tradycyjnej składni:

const article = {
  claps: 0,
  clap: function() {
    this.claps++;
  }
}


Przykład:

 


Prototypy obiektów

Podobnie jak w powyższym przykładzie, prototypy obiektów zewaluują this jako obiekt window, jak w poniższym przykładzie:

class Article {
  constructor(title) {
    this.title = title;
    this.shared = false;
  }
};

Article.prototype.share = () => {
  return this.shared = true;
};


Tak jak w poprzednim przypadku, metoda share() nie zadziała ze względu na to, że zasięgiem jest obiekt window. I znowu rozwiązanie będzie wyglądać podobnie:

Article.prototype.share2 = function() {
  return this.shared = true;
};


Przykład:



Funkcje zwrotne z dynamicznym kontekstem

W następnym przykładzie przyjrzymy się dynamicznemu kontekstowi wywołań zwrotnych, tak jak w przykładzie:

var button = document.getElementById('press');
button.addEventListener('click', () => {
  this.classList.toggle('worked');
});


Podobieństwa z poprzednimi przykładami są oczywiste. Zgadniesz, na czym polega problem? Tak - ponownie zasięg wpływa na znaczenie this.

Przykład:


Sposobem na obejście tego (dzięki michaelbiberich za protip!) jest użycie funkcji strzałkowej i użycie obiektu zdarzenia w celu uzyskania dostępu do obiektu w tej funkcji. To nie rozwiązuje jednak problemu z domknięciem, ale działa dla tego konkretnego przykładu:

var button = document.getElementById('press');
button.addEventListener('click', (e) => {
  e.target.classList.toggle('worked');
});


Mniej czytelny kod

Czasami użycie funkcji strzałkowych spowoduje, że kod będzie nieczytelny. To nie będzie bardzo częste, ale może się zdarzyć. Po prostu ich wtedy nie używaj. W końcu chodzi o to, aby nasz kod był jak najbardziej przejrzysty, więc upewnij się, że tak na pewno jest.


Podsumowanie

ES6 wprowadził wiele świetnych innowacji i funkcje strzałkowe są zdecydowanie jedną z nich. Teraz wiemy już, kiedy nie powinniśmy ich używać oraz jak zorientować się, że z naszym kodem dzieje się coś dziwnego.

Dzięki za przeczytanie!


Oryginał tekstu w języku angielskim przeczytasz tutaj.

Rozpocznij dyskusję

Lubisz dzielić się wiedzą i chcesz zostać autorem?

Podziel się wiedzą z 160 tysiącami naszych czytelników

Dowiedz się więcej