Od jakiegoś czasu eksperymentuję z ES6 i właśnie doszedłem do małego problemu.
Bardzo lubię używać funkcji strzałkowych i kiedy tylko mogę, używam ich.
Jednak wydawałoby się, że nie możesz ich związać!
Oto funkcja:
var f = () => console.log(this);
Oto obiekt, z którym chcę powiązać funkcję:
var o = {'a': 42};
A oto jak bym się związał f
z o
:
var fBound = f.bind(o);
A potem mogę po prostu zadzwonić fBound
:
fBound();
Który wyświetli to ( o
obiekt):
{'a': 42}
Chłodny! Śliczny! Tyle że to nie działa. Zamiast wyprowadzać o
obiekt, wyprowadza window
obiekt.
Więc chciałbym wiedzieć: czy możesz powiązać funkcje strzałkowe? (A jeśli tak, to jak?)
Przetestowałem powyższy kod w Google Chrome 48 i Firefox 43 i wynik jest taki sam.
javascript
function
ecmascript-6
Florrie
źródło
źródło
this
zakresu nadrzędnego.Odpowiedzi:
Nie można ponownie powiązać
this
funkcji strzałkowej. Będzie zawsze definiowany jako kontekst, w którym został zdefiniowany. Jeśli chceszthis
być sensowny, powinieneś użyć normalnej funkcji.Ze specyfikacji ECMAScript 2015 :
źródło
this
. Te dwa są powiązane, ale nie to samo.this
wewnątrz funkcji strzałkowej zawsze „dziedziczy”this
z otaczającego zakresu. To jest cecha funkcji strzałkowych. Ale nadal możeszbind
wszystkie inne parametry funkcji strzałkowej. Po prostu niethis
.Aby być kompletny, to może ponownie wiążą strzałka funkcji, po prostu nie można zmienić znaczenie
this
.bind
nadal ma wartość dla argumentów funkcji:Wypróbuj tutaj: http://jsbin.com/motihanopi/edit?js,console
źródło
this
którego jest przypisana funkcja (strzałka), bez odwoływania się (co jest oczywiście zdefiniowane leksykalnie)?Z MDN :
Oznacza to, że nie możesz przypisać wartości
this
tak, jak chcesz.źródło
Przez lata programiści js zmagali się z wiązaniem kontekstu, pytali, dlaczego
this
zmienił się w javascript, tyle zamieszania przez lata z powodu wiązania kontekstu i różnicy między znaczeniemthis
w javascript ithis
w większości innych języków OOP.Wszystko to prowadzi mnie do pytania, dlaczego, dlaczego! dlaczego miałbyś chcieć ponownie powiązać funkcję strzały! Te, w których tworzone specjalnie, aby rozwiązać wszystkie te problemy i niejasności i uniknąć konieczności użycia
bind
lubcall
czy cokolwiek innego sposobu, aby zachować zakres funkcji.TL; DR
Nie, nie możesz ponownie powiązać funkcji strzałkowych.
źródło
this
nie jest funkcjonalne. lambdy powinny byćarguments => output
. Jeśli potrzebujesz jakiegoś zewnętrznego kontekstu, podaj go. Samo istnieniethis
jest tym, co ułatwiło wprowadzenie do języka wzorców obiektowych. Bez niego nigdy nie słyszałbyś terminu „klasa javascript”.this
.Nie można użyć
bind
do zmiany wartościthis
wewnątrz funkcji strzałkowej. Możesz jednak utworzyć nową zwykłą funkcję, która robi to samo, co stara funkcja strzałkowa, a następnie użyćcall
lub wbind
celu ponownego powiązaniathis
jak zwykle.Używamy
eval
tutaj wywołania, aby odtworzyć funkcję strzałki, którą przekazujesz jako normalną funkcję, a następnie używamycall
do wywołania jej z innąthis
:źródło
Czy funkcje strzałek w ES6 naprawdę rozwiązują „to” w JavaScript
Powyższe łącze wyjaśnia, że funkcje strzałek
this
nie zmieniają się wraz zbind, call, apply
funkcjami.Wyjaśnia to bardzo ładny przykład.
uruchom to,
node v4
aby zobaczyć „oczekiwane” zachowanie,źródło
To samo pytanie zadałem kilka dni temu.
Nie można powiązać wartości, ponieważ
this
jest już powiązana .Powiązanie innego tego zakresu z operatorem funkcji ES6 =>
źródło
this
powiązane " - W zwykłych funkcjach też jest powiązany. Chodzi o to, że w funkcjach strzałkowych nie ma lokalnego powiązania.Krótko mówiąc, NIE MOŻESZ przypisać funkcji strzałek, ale czytaj dalej:
Wyobraź sobie, że masz tę funkcję strzałki poniżej, która
this
wyświetla na konsoli:Szybkim rozwiązaniem byłoby użycie normalnej funkcji, więc po prostu zmień to na:
Następnie możesz powiązać go z dowolnym środowiskiem leksykalnym za pomocą
bind
lubcall
lubapply
:i zadzwoń w przypadku
bind
.Istnieją również sposoby, aby
eval()
to zrobić, co zdecydowanie nie jest zalecane .źródło
function myFunc
jest behawioralnie inny poza możliwością wiązania; bliższe dopasowanie byłobyconst myFunc = function() {...}
. Ciekawi mnie również, co masz na myśli, używając eval, ponieważ jest to podejście, o którym nie sądzę, aby jakaś odpowiedź tu wcześniej udostępniła - ciekawie byłoby zobaczyć, jak to się robi, a następnie przeczytać, dlaczego jest to tak mocno odradzane.Może ten przykład ci pomoże:
źródło