Wcześniej odpowiedzi na pytania tutaj powiedział, że był to najszybszy sposób:
//nl is a NodeList
var arr = Array.prototype.slice.call(nl);
Podczas testów porównawczych w mojej przeglądarce stwierdziłem, że jest on ponad 3 razy wolniejszy niż to:
var arr = [];
for(var i = 0, n; n = nl[i]; ++i) arr.push(n);
Oba generują tę samą moc wyjściową, ale trudno mi uwierzyć, że moja druga wersja jest najszybszym możliwym sposobem, zwłaszcza że ludzie mówią tutaj inaczej.
Czy to dziwactwo w mojej przeglądarce (Chromium 6)? Czy jest szybszy sposób?
EDYCJA: Dla każdego, kogo to obchodzi, zdecydowałem się na następujące (co wydaje się najszybsze w każdej testowanej przeglądarce):
//nl is a NodeList
var l = []; // Will hold the array of Node's
for(var i = 0, ll = nl.length; i != ll; l.push(nl[i++]));
EDIT2: Znalazłem jeszcze szybszy sposób
// nl is the nodelist
var arr = [];
for(var i = nl.length; i--; arr.unshift(nl[i]));
javascript
arrays
nodelist
jairajs89
źródło
źródło
arr[arr.length] = nl[i];
może być szybszy niż,arr.push(nl[i]);
ponieważ pozwala uniknąć wywołania funkcji.var i = nl.length, arr = new Array(i); for(; i--; arr[i] = nl[i]);
Odpowiedzi:
Drugi jest zazwyczaj szybszy w niektórych przeglądarkach, ale najważniejsze jest to, że musisz go używać, ponieważ pierwszy nie jest po prostu przeznaczony dla różnych przeglądarek. Nawet jeśli czasy się zmieniają
@kangax ( podgląd IE 9 )
Przykład:
źródło
W ES6 mamy teraz prosty sposób na utworzenie tablicy z NodeList:
Array.from()
funkcję.źródło
console.log(Array.from([1, 2, 3], x => x + x)); // expected output: Array [2, 4, 6]
Oto nowy fajny sposób na zrobienie tego za pomocą operatora rozprzestrzeniania ES6 :
źródło
ERROR TypeError: el.querySelectorAll(...).slice is not a function
Niektóre optymalizacje:
Kod ( jsPerf ):
źródło
Wyniki będą całkowicie zależeć od przeglądarki, aby dać obiektywny werdykt, musimy wykonać testy wydajności, oto kilka wyników, które możesz uruchomić tutaj :
Chrome 6:
Firefox 3.6:
Firefox 4.0b2:
Safari 5:
Przegląd platformy IE9 3:
źródło
for (var i=o.length; i--;)
... czy „for loop” w tych testach przewartościowała właściwość długości przy każdej iteracji?Najszybsza i największa przeglądarka to
Jak porównałem w
http://jsbin.com/oqeda/98/edit
* Dzięki @CMS za pomysł!
źródło
W ES6 możesz użyć:
Array.from
let array = Array.from(nodelist)
Operator rozsiewu
let array = [...nodelist]
źródło
Teraz możesz zrobić document.querySelectorAll ('div'). ForEach (function () ...)
źródło
NodeList
nie działa, aleObject
:Object.prototype.forEach = Array.prototype.forEach; document.getElementsByTagName("img").forEach(function(img) { alert(img.src); });
szybciej i krócej:
źródło
>>>0
? A dlaczego nie umieścić zadań w pierwszej części pętli for?l
jest0
, pętla się kończy, dlatego0
element th nie zostanie skopiowany (pamiętaj, że element ma indeks0
)>>>
może nie być tutaj konieczny, ale służy do zagwarantowania długości listy węzłów zgodnie ze specyfikacją tablicy; zapewnia, że jest to 32-bitowa liczba całkowita bez znaku. Sprawdź tutaj ecma-international.org/ecma-262/5.1/#sec-15.4 Jeśli podoba Ci się nieczytelny kod, użyj tej metody z sugestiami @ CamiloMartin!var
do pierwszej częścifor
pętli jest ryzykowne z powodu „zmiennego podnoszenia”. Deklaracjavar
zostanie „podniesiona” na górę funkcji, nawet jeślivar
linia pojawi się gdzieś niżej, co może powodować skutki uboczne, które nie są oczywiste z sekwencji kodu. Na przykład niektóre kodu w tej samej funkcji występujący przed dla pętli może zależeć naa
il
jest nielegalnej. Dlatego, aby uzyskać większą przewidywalność, zadeklaruj swoje zmienne na górze funkcji (lub jeśli na ES6, użyjconst
lublet
zamiast tego, które nie podnoszą).Sprawdź ten post na blogu , który mówi o tym samym. Z tego, co zbieram, dodatkowy czas może mieć związek z przejściem w górę łańcucha lunety.
źródło
Array.prototype.slice
to, że zależy od przeglądarki. Zastanawiam się, jakiego algorytmu używa każda z przeglądarek.Z tej funkcji korzystam w JS:
źródło
Oto wykresy zaktualizowane na dzień opublikowania (wykres „nieznanej platformy” to Internet Explorer 11.15.16299.0):
Na podstawie tych wyników wydaje się, że metoda preallocate 1 jest najbezpieczniejszym zakładem dla różnych przeglądarek.
źródło
Zakładając
nodeList = document.querySelectorAll("div")
, że jest to zwięzła forma konwersjinodelist
na tablicę.Zobacz mnie, użyj go tutaj .
źródło