Zuvor beantwortete Fragen hier sagten, dass dies der schnellste Weg war:
//nl is a NodeList
var arr = Array.prototype.slice.call(nl);
Beim Benchmarking in meinem Browser habe ich festgestellt, dass es mehr als dreimal langsamer ist als dieses:
var arr = [];
for(var i = 0, n; n = nl[i]; ++i) arr.push(n);
Beide produzieren die gleiche Ausgabe, aber ich kann kaum glauben, dass meine zweite Version der schnellstmögliche Weg ist, zumal die Leute hier etwas anderes gesagt haben.
Ist das eine Eigenart in meinem Browser (Chromium 6)? Oder gibt es einen schnelleren Weg?
EDIT: Für alle, die sich interessieren, habe ich mich für Folgendes entschieden (das in jedem von mir getesteten Browser am schnellsten zu sein scheint):
//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: Ich habe einen noch schnelleren Weg gefunden
// nl is the nodelist
var arr = [];
for(var i = nl.length; i--; arr.unshift(nl[i]));
javascript
arrays
nodelist
jairajs89
quelle
quelle
arr[arr.length] = nl[i];
kann schneller sein alsarr.push(nl[i]);
da es einen Funktionsaufruf vermeidet.var i = nl.length, arr = new Array(i); for(; i--; arr[i] = nl[i]);
Antworten:
Der zweite ist in einigen Browsern tendenziell schneller, aber der Hauptpunkt ist, dass Sie ihn verwenden müssen, da der erste einfach nicht browserübergreifend ist. Auch wenn die Zeiten, in denen sie a-Changin sind
@ Kangax ( IE 9 Vorschau )
Beispiel:
quelle
Mit ES6 haben wir jetzt eine einfache Möglichkeit, ein Array aus einer NodeList zu erstellen: die
Array.from()
Funktion.quelle
console.log(Array.from([1, 2, 3], x => x + x)); // expected output: Array [2, 4, 6]
Hier ist eine neue coole Möglichkeit, dies mit dem ES6-Spread-Operator zu tun :
quelle
ERROR TypeError: el.querySelectorAll(...).slice is not a function
Einige Optimierungen:
Code ( jsPerf ):
quelle
Die Ergebnisse hängen vollständig vom Browser ab. Um ein objektives Urteil zu fällen, müssen wir einige Leistungstests durchführen. Hier sind einige Ergebnisse, die Sie ausführen können hier :
Chrome 6:
Firefox 3.6:
Firefox 4.0b2:
Safari 5:
IE9 Platform Preview 3:
quelle
for (var i=o.length; i--;)
Hat die 'for-Schleife' in diesen Tests die Längeneigenschaft bei jeder Iteration neu bewertet?Der schnellste und browserübergreifendste ist
Wie ich in verglichen habe
http://jsbin.com/oqeda/98/edit
* Danke @CMS für die Idee!
quelle
In ES6 können Sie entweder Folgendes verwenden:
Array.from
let array = Array.from(nodelist)
Spread-Operator
let array = [...nodelist]
quelle
Jetzt können Sie document.querySelectorAll ('div'). ForEach (function () ...) ausführen.
quelle
NodeList
nicht, sondernObject
:Object.prototype.forEach = Array.prototype.forEach; document.getElementsByTagName("img").forEach(function(img) { alert(img.src); });
schneller und kürzer:
quelle
>>>0
? Und warum nicht die Zuweisungen in den ersten Teil der for-Schleife setzen?l
ist0
, endet die Schleife, daher wird das0
dritte Element nicht kopiert (denken Sie daran, dass sich ein Element im Index befindet0
)>>>
möglicherweise nicht notwendig, wird aber verwendet, um zu gewährleisten, dass die Länge der Knotenliste der Array-Spezifikation entspricht. Es stellt sicher, dass es sich um eine vorzeichenlose 32-Bit-Ganzzahl handelt. Überprüfen Sie es hier ecma-international.org/ecma-262/5.1/#sec-15.4 Wenn Sie unlesbaren Code mögen, verwenden Sie diese Methode mit den Vorschlägen von @ CamiloMartin!var
den ersten Teil einerfor
Schleife zu platzieren, da es sich um ein "variables Heben" handelt. Die Deklaration vonvar
wird an den oberenvar
Rand der Funktion "gehisst", auch wenn die Zeile irgendwo weiter unten angezeigt wird. Dies kann zu Nebenwirkungen führen, die aus der Codesequenz nicht ersichtlich sind. Zum Beispiel auftreten einige Code in der gleichen Funktion vor der for - Schleife könnte abhängen aufa
undl
nicht deklariert werden. Deklarieren Sie daher für eine bessere Vorhersagbarkeit Ihre Vars oben in der Funktion (oder verwenden Sie bei ES6const
oderlet
stattdessen, die nicht hochgezogen werden).Schauen Sie sich diesen Blog-Beitrag hier an , der über dasselbe spricht. Soweit ich weiß, hat die zusätzliche Zeit möglicherweise damit zu tun, die Zielfernrohrkette hinaufzugehen.
quelle
Array.prototype.slice
browserabhängig ist. Ich frage mich, welchen Algorithmus jeder Browser verwendet.Dies ist die Funktion, die ich in meinem JS verwende:
quelle
Hier sind die zum Datum dieser Veröffentlichung aktualisierten Diagramme (Diagramm "unbekannte Plattform" ist Internet Explorer 11.15.16299.0):
Aus diesen Ergebnissen geht hervor, dass die Methode der Vorbelegung 1 die sicherste Cross-Browser-Wette ist.
quelle
Angenommen
nodeList = document.querySelectorAll("div")
, dies ist eine prägnante Form der Konvertierungnodelist
in ein Array.Sehen Sie, wie ich es hier benutze .
quelle