2013-06-09 7 views
9

stary sposób:

var self = this;  
setTimeout(function(){ 
    console.log(self); 
}, 5000); 

z jQuery:

setTimeout($.proxy(function(){ 
    console.log(this); 
}, this), 5000); 

Z wiąże:

setTimeout((function(){ 
    console.log(this); 
}).bind(this), 5000); 

Z rozmowy:

setTimeout((function(){ 
    console.log(this); 
}).call(this), 5000); 

Wydaje się, że zastosowanie prace zbyt:

setTimeout((function(){ 
    console.log(this); 
}).apply(this), 5000); 

http://jsfiddle.net/SYajz/1/

Zastanawiałem się, czy są jakieś nie tak oczywiste różnice pomiędzy tymi metodami

+0

Twoje dwa ostatnie przykłady nie działają - natychmiast wywołują wywołanie zwrotne. – Alnitak

Odpowiedz

9

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.

4

Z $.proxy i .bind(), tworzysz nowy funkcja o wartości this powiązanej z podaną wartością. Jest to funkcja, która zostaje przekazana do setTimeout().


Z .call() i .apply() jesteś natychmiast wywołując funkcję, więc to nie będzie czekać na zegar.

Dla tych, do pracy z zegarem, trzeba by powrócić do funkcji, które zamyka się nad zmienną, która odwołuje się do podanej wartości this i wywołuje console.log() daną odwołanie this się.

setTimeout((function(){ 
    var that = this; 
    return function() { 
     console.log(that); 
    } 
}).call(this), 5000);