2009-12-29 10 views

Odpowiedz

24

Zastosowanie apply jest związane z kontekstem funkcji (słowo kluczowe this) i przekazywaniem argumentów.

Po pierwsze, myślę, że powinieneś wiedzieć, w jakich przypadkach kluczowe this jest niejawnie zestaw:

1- Gdy funkcja jest wywoływana jako metoda (funkcja jest wywoływana jako członek obiektu):

obj.method(); // 'this' inside method will refer to obj 

2- przy wywołaniu funkcji:

myFunction(); // 'this' inside the function will refer to the Global object 
// or 
(function() {})(); 

3- Gdy new operator jest używany:

var obj = new MyObj(); // this will refer to a newly created object. 

Oto gdy apply i call przyjść, metody te pozwalają ustawić wyraźnie kontekst podczas wywołania funkcji, np .:

function test(a) { 
    alert(this + a); 
} 

test.call('Hello', ' world!'); 

W powyższym kodzie , gdy wywoływana jest funkcja test ustawiająca słowo kluczowe this na łańcuch znaków ('Hello') i przekazująca argument a (' world.').

Zarówno call i apply zmienić kontekst funkcji wykonującego (słowa kluczowego this) wewnątrz wywołanej funkcji, ale różnica między nimi jest to, że z apply można wysłać tablicę lub obiekt Array podobny jak argumenty funkcji do wykonania, co jest niezwykle przydatne, na przykład:

function sum() { 
    var result = 0; 
    for (var i = 0; i < arguments.length; i++) { 
    result += arguments[i]; 
    } 
    return result; 
} 

var args = [1,2,3]; 
sum.apply(null, args); // will return 6 

to może uniknąć pewnych bardzo hacky, złych (i wspólne) eval połączeń typu:

eval('sum(' + args.join() +')'); 

Innym przykładem, metody Math.max i Math.min, metody te można otrzymać dowolną liczbę argumentów, takich jak:

var max = Math.max(2,4,6,8); // 8 

ale co jeśli masz tablicę liczb?

var numbers = [2,4,6,8]; 
numbers.push(10); 
var max = Math.max.apply(null, numbers); // 10 

Należy również pamiętać, że gdy null lub undefined służy jako this argumentu z call lub apply, obiekt this będzie odnosić się do globalnego obiektu (podobnie jak w przypadku # 2, normalna funkcja wywołania).

Dla przykładu Math.max, kontekst nie jest to istotne, ponieważ są one po prostu jak „statyczne” metody, słowo this nie jest używane wewnętrznie ...

+3

+1 Bardzo ładne! ---- –

+0

Ah Myślę, że rozumiem to teraz. Cały punkt, który przeoczyłem, to "wartość tego jest podana jako pierwsze parametry". Teraz ma sens, dlaczego chcielibyśmy różnicować metodę stosowania jako osobny rodzaj inwokacji. Czym jest różnica. między słowami "zadzwoń" i zastosuj słowa kluczowe? – Priyank

+0

@ cms +1 idealny do wydrukowania! –

0

nie jestem świadomy każdego projektu wzorce o nazwie The Apply Pattern, więc naprawdę nie sądzę, że jest to w ogóle związane ze wzorami projektowymi. Istnieje jednak metoda stosowania obiektów funkcji w javascript (wraz z odpowiednią metodą wywołania), więc wytłumaczę to.

Metody stosowania i wywołania w zasadzie umożliwiają obiektowi "kradzież" metody z innego obiektu. Widzisz, w javascriptie metody są bardzo późno związane: w czasie wywołania. Dopiero po wywołaniu metody rozwiązana zostanie wartość 'this'. W normalnym sposobem połączenia:

some_object.do_something(); 

'this' kluczowe w do_something dotyczy some_object. Zastosuj i zadzwoń pozwala ponownie przypisać 'this'. Na przykład:

some_object.do_something.apply(another_object); 

'this' kluczowe w do_something odnosi się teraz do another_object. Więc wywołujesz metodę do_something należącą do some_object na another_object.

To ciekawe i wszystkie, ale dlaczego ktoś chciałby to zrobić? Oto konkretny przykład, dlaczego to jest przydatne:

// say you want to get some DIVs in the document, you can get all of them with: 
var some_divs = document.getElementsByTagName('DIV'); 

// say you want the third to fifth DIV in the document, some_divs looks like an 
// array so you might think you can slice it, but it's not. It's a collection 
// of elements that fakes being an array and doesn't implement the slice method. 

// No worries, we can steal the slice method from an array 
// and apply it to some_divs: 
var wanted_divs = [].slice.apply(some_divs,[2,5]); 

// Alternatively: 
var wanted_divs = [].slice.call(some_divs,2,5); 

Jest jeszcze inny przypadek użycia przez zastosowanie co jest wynikiem różnicy w jaki sposób stosować i prace zadzwonić. Jeśli masz wszystkie swoje argumenty w tablicy, a funkcja oczekuje poszczególnych argumentów można użyć zastosować przekazać tablicę i posiada funkcję zobaczyć zawartość tablicy jako osobne argumenty

function some_function (first,second) { 
    alert(first+second); 
} 
var argument_array = ['hello','world']; 
some_function.apply(null, argument_array); 
1

Można również użyć połączenia/złożyć wniosek o dziedziczenie.

function Client (id) { 
    this.id = id; 
    this.name = "Client" + id; 
} 

Client.prototype = { 
    constructor: Client 

    , toString: function() { 
     return this.name; 
    } 
}; 

function WebClient (id) { 
    Client.call (this, id); 
} 

WebClient.prototype = new Client(); 

WebClient.prototype.constructor = WebClient; 

WebClient.prototype.ping = function() { 
    // do stuff 
}; 

Wskazówka Client.call (this, id); ten wykonuje Client pomocą instancji this że new WebClient powodowałaby. Tak więc, gdy

this.id = id; 
    this.name = "Client" + id; 

są wykonywane wewnątrz Client instancja WebClient jest uzyskiwanie przypisane te właściwości.

Powiązane problemy