¿La forma más rápida de convertir JavaScript NodeList a Array?
Las preguntas respondidas anteriormente aquí decían 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 de 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 de mi navegador (Chromium 6)? ¿O hay una manera más rápida?
Con ES6, ahora tenemos una forma sencilla de crear una matriz a partir de una lista de nodos: la Array.from()
función.
// nl is a NodeList
let myArray = Array.from(nl)
Actualización de 2021: nodeList.forEach() ahora es estándar y compatible con todos los navegadores actuales ( alrededor del 95% tanto en computadoras de escritorio como en dispositivos móviles ).
Entonces simplemente puedes hacer:
document.querySelectorAll('img').forEach(highlight);
Otros casos
Si por alguna razón desea convertirlo en una matriz, no solo iterar sobre él, lo cual es un caso de uso completamente relevante, puede usar [...destructuring]
o Array.from
desde ES6
let array1 = [...mySetOfElements];
// or
let array2 = Array.from(mySetOfElements);
Esto también funciona para otras estructuras tipo matriz que no son NodeLists
HTMLCollection
devuelto por ej.document.getElementsByTagName
- objetos con una propiedad de longitud y elementos indexados
- objetos iterables (objetos como
Map
ySet
)
Respuesta obsoleta de 2010
El segundo tiende a ser más rápido en algunos navegadores, pero el punto principal es que debes usarlo porque el primero simplemente no es compatible con todos los navegadores. Aunque los tiempos están cambiando
@kangax ( vista previa de IE 9 )
Array.prototype.slice ahora puede convertir ciertos objetos host (por ejemplo, NodeList) en matrices, algo que la mayoría de los navegadores modernos han podido hacer durante bastante tiempo.
Ejemplo:
Array.prototype.slice.call(document.childNodes);
Aquí hay una nueva manera genial de hacerlo usando el operador de extensión de ES6 :
let arr = [...nl];
En ES6 puedes usar:
matriz.de
let array = Array.from(nodelist)
Operador de propagación
let array = [...nodelist]