Las preguntas respondidas anteriormente aquí dijeron que esta era la forma más rápida:
//nl is a NodeList
var arr = Array.prototype.slice.call(nl);
Al realizar una evaluación comparativa en mi navegador, descubrí que es más de 3 veces más lento que esto:
var arr = [];
for(var i = 0, n; n = nl[i]; ++i) arr.push(n);
Ambos producen el mismo resultado, pero me resulta difícil creer que mi segunda versión sea la forma más rápida posible, especialmente porque la gente ha dicho lo contrario aquí.
¿Es esto una peculiaridad en mi navegador (Chromium 6)? ¿O hay una manera más rápida?
EDITAR: Para cualquier persona que se preocupe, me decidí por lo siguiente (que parece ser el más rápido en todos los navegadores que probé):
//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: encontré una forma aún más rápida
// nl is the nodelist
var arr = [];
for(var i = nl.length; i--; arr.unshift(nl[i]));
javascript
arrays
nodelist
jairajs89
fuente
fuente
arr[arr.length] = nl[i];
puede ser más rápido quearr.push(nl[i]);
ya que evita una llamada de función.var i = nl.length, arr = new Array(i); for(; i--; arr[i] = nl[i]);
Respuestas:
El segundo tiende a ser más rápido en algunos navegadores, pero el punto principal es que debe usarlo porque el primero simplemente no es cruzado. A pesar de que The Times They are a-Changin '
@kangax ( vista previa de IE 9 )
Ejemplo:
fuente
Con ES6, ahora tenemos una forma sencilla de crear una matriz a partir de una NodeList: la
Array.from()
función.fuente
console.log(Array.from([1, 2, 3], x => x + x)); // expected output: Array [2, 4, 6]
Aquí hay una nueva forma genial de hacerlo utilizando el operador de propagación ES6 :
fuente
ERROR TypeError: el.querySelectorAll(...).slice is not a function
Algunas optimizaciones:
Código ( jsPerf ):
fuente
Los resultados dependerán completamente del navegador, para dar un veredicto objetivo, tenemos que hacer algunas pruebas de rendimiento, aquí hay algunos resultados, puede ejecutarlos aquí :
Chrome 6:
Firefox 3.6:
Firefox 4.0b2:
Safari 5:
Vista previa de la plataforma IE9 3:
fuente
for (var i=o.length; i--;)
... ¿el 'bucle for' en estas pruebas reevaluó la propiedad de longitud en cada iteración?El navegador más rápido y cruzado es
Como lo comparé en
http://jsbin.com/oqeda/98/edit
* ¡Gracias @CMS por la idea!
fuente
En ES6 puedes usar:
Array.from
let array = Array.from(nodelist)
Operador extendido
let array = [...nodelist]
fuente
Ahora puede hacer document.querySelectorAll ('div'). ForEach (function () ...)
fuente
NodeList
no funciona pero síObject
:Object.prototype.forEach = Array.prototype.forEach; document.getElementsByTagName("img").forEach(function(img) { alert(img.src); });
más rápido y más corto:
fuente
>>>0
? ¿Y por qué no poner las tareas en la primera parte del ciclo for?l
es así0
, el ciclo finalizará, por lo tanto, el0
elemento th no se copiará (recuerde que hay un elemento en el índice0
)>>>
puede que no sea necesario aquí, pero se utiliza para garantizar que la longitud de la lista de nodos se adhiera a las especificaciones de la matriz; asegura que es un entero de 32 bits sin signo. Compruébelo aquí ecma-international.org/ecma-262/5.1/#sec-15.4 Si le gusta el código ilegible, ¡use este método con las sugerencias de @ CamiloMartin!var
dentro de la primera parte de unfor
bucle debido a la 'elevación variable'. La declaración devar
'se izará' en la parte superior de la función, incluso si lavar
línea aparece en algún lugar más abajo, y esto puede causar efectos secundarios que no son obvios en la secuencia del código. Por ejemplo algo de código en la misma función que ocurre antes el bucle podría depender ena
yl
siendo no declarado. Por lo tanto, para una mayor capacidad de predicción, declare sus variables en la parte superior de la función (o si está en ES6, useconst
o en sulet
lugar, que no se iza).Mira esta publicación de blog aquí que habla sobre lo mismo. Por lo que deduzco, el tiempo extra podría tener que ver con subir la cadena del telescopio.
fuente
Array.prototype.slice
depende del navegador. Me pregunto qué algoritmo está usando cada uno de los navegadores.Esta es la función que uso en mi JS:
fuente
Aquí hay gráficos actualizados a la fecha de esta publicación (el cuadro de "plataforma desconocida" es Internet Explorer 11.15.16299.0):
A partir de estos resultados, parece que el método de preasignación 1 es la apuesta más segura entre navegadores.
fuente
Suponiendo
nodeList = document.querySelectorAll("div")
, esta es una forma concisa de convertirnodelist
a matriz.Véame usarlo aquí .
fuente