Dobrze, więc mamy trzy style wywoływania funkcji tutaj. Są one wszystkie sposoby rozwiązania problemu z tym, że słowo kluczowe this
ma inną wartość, w zależności od sposobu wywołania tej funkcji.
aliasing
var self = this;
setTimeout(function(){
console.log(self);
}, 5000);
Jest to bardzo prosty sposób. Po prostu ustawia nową zmienną, która nie zostanie nadpisana w funkcji. Wartość jest zamknięta, więc gdy funkcja zostanie wywołana po upływie limitu czasu, self
będzie tym, czego oczekujesz.
Wiążące
setTimeout($.proxy(function(){
console.log(this);
}, this), 5000);
setTimeout((function(){
console.log(this);
}).bind(this), 5000);
Te dwie funkcje mają identyczne wyniki. Jest tak, ponieważ $.proxy
robi dokładnie to samo, co bind
. bind
jest jednak nową składnią, która nie jest obsługiwana przez niektóre starsze przeglądarki.
Działa to przez trwałe powiązanie kontekstu z funkcją. Oznacza to, że jakkolwiek funkcja jest wywoływana, wartość this
zawsze będzie wartością pierwszego argumentu dla bind
.
call
/apply
setTimeout((function(){
console.log(this);
}).call(this), 5000);
setTimeout((function(){
console.log(this);
}).apply(this), 5000);
Ponownie, obie te funkcje są identyczne. Jedyną różnicą między call
i apply
jest to, jakie inne parametry są wysyłane do funkcji. call
oczekuje listy (na przykład fn.call(context, param1, param2)
), podczas gdy apply
oczekuje tablicy (fn.apply(context, [param1, param2])
).
To, co robią obie te funkcje, to wywołanie funkcji z określonym określonym kontekstem.
Jednak żadna z tych funkcji nie spełnia Twoich oczekiwań. Obaj wywołują funkcję natychmiast w określonym kontekście, zamiast czekać 5 sekund, aby to zrobić. To dlatego, że call
i apply
działają tak jak ()
: kod jest wykonywany natychmiast.
Wnioski
Która metoda jest bardziej odpowiedni będzie zależeć od zadania. W przypadku prostych operacji aliasowanie może dobrze wykonać zadanie. Warto jednak pamiętać, że wprowadza ona inną zmienną i że kontekstu nie można ustawić w czasie połączenia. Inne metody mają także swoje mocne strony w różnych sytuacjach, szczególnie podczas pisania biblioteki, w której użytkownicy dostarczają funkcje wywołania zwrotnego.
Twoje dwa ostatnie przykłady nie działają - natychmiast wywołują wywołanie zwrotne. – Alnitak