As perguntas anteriormente respondidas aqui disseram que esse era o caminho mais rápido:
//nl is a NodeList
var arr = Array.prototype.slice.call(nl);
Nos testes comparativos no meu navegador, descobri que é mais de três vezes mais lento que isso:
var arr = [];
for(var i = 0, n; n = nl[i]; ++i) arr.push(n);
Ambos produzem a mesma saída, mas acho difícil acreditar que minha segunda versão seja a maneira mais rápida possível, principalmente porque as pessoas disseram o contrário aqui.
Isso é uma peculiaridade no meu navegador (Chromium 6)? Ou existe uma maneira mais rápida?
EDIT: Para quem se importa, decidi o seguinte (que parece ser o mais rápido em todos os navegadores que testei):
//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: Encontrei uma maneira ainda mais rápida
// nl is the nodelist
var arr = [];
for(var i = nl.length; i--; arr.unshift(nl[i]));
javascript
arrays
nodelist
jairajs89
fonte
fonte
arr[arr.length] = nl[i];
pode ser mais rápido do quearr.push(nl[i]);
porque evita uma chamada de função.var i = nl.length, arr = new Array(i); for(; i--; arr[i] = nl[i]);
Respostas:
O segundo tende a ser mais rápido em alguns navegadores, mas o ponto principal é que você precisa usá-lo porque o primeiro não é apenas um navegador cruzado. Mesmo que os tempos estejam mudando
@kangax ( pré-visualização do IE 9 )
Exemplo:
fonte
Com o ES6, agora temos uma maneira simples de criar uma matriz a partir de uma NodeList: a
Array.from()
funçãofonte
console.log(Array.from([1, 2, 3], x => x + x)); // expected output: Array [2, 4, 6]
Aqui está uma nova maneira interessante de fazer isso usando o operador de spread ES6 :
fonte
ERROR TypeError: el.querySelectorAll(...).slice is not a function
Algumas otimizações:
Código ( jsPerf ):
fonte
Os resultados dependerão completamente do navegador, para dar um veredicto objetivo, temos que fazer alguns testes de desempenho, aqui estão alguns resultados, você pode executá-los aqui :
Chrome 6:
Firefox 3.6:
Firefox 4.0b2:
Safari 5:
Prévia da plataforma IE9 3:
fonte
for (var i=o.length; i--;)
... o 'loop for' nesses testes reavalia a propriedade length em todas as iterações?O navegador mais rápido e cruzado é
Como eu comparei em
http://jsbin.com/oqeda/98/edit
* Obrigado @CMS pela ideia!
fonte
No ES6, você pode usar:
Array.from
let array = Array.from(nodelist)
Operador de propagação
let array = [...nodelist]
fonte
Agora você pode fazer document.querySelectorAll ('div'). ForEach (function () ...)
fonte
NodeList
não está funcionando, masObject
é: #Object.prototype.forEach = Array.prototype.forEach; document.getElementsByTagName("img").forEach(function(img) { alert(img.src); });
mais rápido e mais curto:
fonte
>>>0
? E por que não colocar as atribuições na primeira parte do loop for?l
é0
, o ciclo termina, por conseguinte, o0
elemento th não será copiado (Remeber há um elemento no índice0
)>>>
pode não ser necessário aqui, mas é usado para garantir que o comprimento do modelista adira às especificações da matriz; garante que seja um número inteiro de 32 bits não assinado. Confira aqui ecma-international.org/ecma-262/5.1/#sec-15.4 Se você gosta de código ilegível, use este método com as sugestões de @ CamiloMartin!var
inserir a primeira parte de umfor
loop por causa de 'içamento variável'. A declaração devar
será 'içada' na parte superior da função, mesmo que avar
linha apareça em algum lugar abaixo, e isso pode causar efeitos colaterais que não são óbvios na sequência de código. Por exemplo um código na a mesma função que ocorre antes de o loop pode depender ema
el
sendo não declarado. Portanto, para maior previsibilidade, declare seus vars na parte superior da função (ou, no ES6, useconst
oulet
não, que não sejam içados).Confira este post aqui que fala sobre a mesma coisa. Pelo que entendi, o tempo extra pode ter a ver com subir a cadeia de escopo.
fonte
Array.prototype.slice
depende do navegador. Gostaria de saber qual algoritmo cada navegador está usando.Esta é a função que eu uso no meu JS:
fonte
Aqui estão os gráficos atualizados na data desta postagem (o gráfico "plataforma desconhecida" é o Internet Explorer 11.15.16299.0):
A partir desses resultados, parece que o método de pré-alocação 1 é a aposta mais segura entre navegadores.
fonte
Supondo que
nodeList = document.querySelectorAll("div")
esta seja uma forma concisa de conversãonodelist
em matriz.Veja-me usá-lo aqui .
fonte