2011-02-28 15 views
46

właśnie przeglądanie kodu źródłowego trzask i natknąłem się na tej linii kodu:Jaki jest pożytek z Array.prototype.slice.call (array, 0)?

array = Array.prototype.slice.call(array, 0); 

Podniosłem wzrok co funkcja jest, ale doszedłem do wniosku, że po prostu zwraca wszystkie elementy tablicy, począwszy od indeks 0 i umieszcza całość w tablicy, tzn. w rzeczywistości nic nie robi.

Co to jest użycie tej linii kodu? czego mi brakuje?

Edytuj: To jest linia 863 z https://github.com/jquery/sizzle/blob/master/sizzle.js#L863.

+1

Wydaje się, że jest to nieco zawikłany sposób wywoływania funkcji 'tablica.slice (0)', która tworzy kopię tablicy. Nie rozumiem, dlaczego nazywa się to w tak nieprzenikniony sposób. – spender

+8

Kontekst robi różnicę. Identyfikator 'tablica' nie odwołuje się do rzeczywistej tablicy. – user113716

Odpowiedz

75

DOM zwykle zwraca wartość NodeList dla większości operacji, takich jak getElementsByTagName.

Mimo że NodeList prawie wydaje się być tablicą, nie jest. Ma ona właściwość taką jak tablica i metodę item(index) uzyskiwania dostępu do obiektu przy danym indeksie (dostępnym również z notacją [index]), ale tam kończy się podobieństwo.

Aby móc używać wspaniałego array methods bez przepisywania ich wszystkich na NodeList, powyższa linia jest przydatna.

Innym zastosowaniem konwersji do tablicy jest uczynienie listy statyczną. NodeLists są zwykle aktywne, co oznacza, że ​​jeśli nastąpi zmiana dokumentu, obiekt NodeList zostanie automatycznie zaktualizowany. Mogłoby to spowodować problemy, gdyby obiekt jQuery, który powrócił, zmienił się tuż pod twoim nosem. Wypróbuj następujące snippet, aby przetestować żywotność węzłów NodeLists.

var p = document.getElementsByTagName('p'); 
console.log(p.length); // 2 
document.body.appendChild(document.createElement('p')); 
// length of p changes as document was modified 
console.log(p.length); // 3 
+3

Ta odpowiedź doprowadza mnie o krok bliżej do objęcia JS. Od lat mam nadzieję, że to po prostu zniknie ... i tak +1 do ciebie. – Lee

+0

Powstało pytanie, z którego wynika, skąd wiadomo, do jakich obiektów można zastosować metody tablic? Podobno jest to dowolny obiekt z właściwością length i nazwami właściwości całkowitymi (które zaczynają się od zera?). Nauczyłem się również, że zmienna "arguments" jest obiektem typu tablica, ale nie jest faktyczną tablicą (nie wiedziałem). Odpowiedź była tutaj: http://stackoverflow.com/questions/7056925/how-does-array-prototype-slice-call-work – zod

+1

@zod: Jeśli spojrzeć na [implementację V8] (http://code.google .com/p/v8/source/browse/trunk/src/array.js # 617) to tam [nie wydaje się] (http://code.google.com/p/v8/source/browse/trunk/ src/array.js # 321) by być czymś magicznym. Używa '.length' do określenia zakresu, a następnie wykonuje pętlę' for', aby skopiować właściwe elementy (co wymaga tylko obiektu z kluczami numerycznymi). – pimvdb

6

Jak mówi BoltClock, tworzy płytką kopię tablicy. Można go również użyć do skopiowania czegoś, co jest wbudowaną tablicą, taką jak wbudowana, która ma długość i elementy, ale nie ma tablicy w łańcuchu prototypów (a zatem nie ma metody wycinania).

+0

Myślałem, że tak, ale przypisuje wynik z powrotem do tej samej tablicy ", więc nie mogę się dowiedzieć, co naprawdę się dzieje. – BoltClock

+0

Czy mogę zapytać, dlaczego 'var' nie jest umieszczona przed nim? Jeśli zostanie wykonana kopia, to czy nie byłaby to nowa zmienna, tj. Z 'var'? – pimvdb

+0

@BoltClock, Hmmm ... to dziwne. Być może chodzi o to, aby dać prototypowi Array coś, co nie jest tak naprawdę, jak argumenty lub zestaw jQuery. – harpo

10

To, co dzieje się tutaj, polega na tym, że Sizzle tworzy rzeczywisty układ z obiektu tablicowego. Obiekt podobny do tablicy niekoniecznie musi mieć metodę slice(), więc prototypową metodę należy wywołać bezpośrednio. makeArray() zwraca kopię tego obiektu tablicowego, która jest rzeczywistą tablicą i może być używana jako taka w innym miejscu.

Więcej informacji na temat obiektów tablicowych można znaleźć pod numerem here.

Powiązane problemy