Le moyen le plus rapide de convertir JavaScript NodeList en Array?

Les réponses précédentes ont indiqué que c'était le moyen le plus rapide:

//nl is a NodeList var arr = Array.prototype.slice.call(nl); 

Dans le benchmarking sur mon navigateur, j'ai constaté qu'il est plus de 3 fois plus lent que ceci:

 var arr = []; for(var i = 0, n; n = nl[i]; ++i) arr.push(n); 

Ils produisent tous deux la même sortie, mais j'ai du mal à croire que ma deuxième version est la manière la plus rapide possible, d'autant plus que les gens ont dit autrement ici.

Est-ce une gêne dans mon navigateur (Chromium 6)? Ou est-il plus rapide?

EDIT: Pour tous ceux qui s'en soucient, je me suis installé sur ce qui suit (qui semble être le plus rapide dans tous les navigateurs que j'ai testés):

 //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: j'ai trouvé un moyen encore plus rapide

 // nl is the nodelist var arr = []; for(var i = nl.length; i--; arr.unshift(nl[i])); 

Le second a tendance à être plus rapide dans certains navigateurs, mais le point principal est que vous devez l'utiliser car le premier n'est pas un navigateur croisé. Même si The Times They Are a-Changin '

@kangax ( aperçu IE 9 )

Array.prototype.slice peut maintenant convertir certains objets hôtes (par exemple, NodeList's) en tableaux – quelque chose que la majorité des navigateurs modernes ont pu faire pendant un bon moment.

Exemple:

 Array.prototype.slice.call(document.childNodes); 

Avec ES6, nous avons maintenant un moyen simple de créer une matrice à partir d'une liste de nœuds:

 // nl is a NodeList let myArray = Array.from(nl) 

Voici un nouveau moyen de le faire en utilisant l' opérateur ES6 spread :

 let arr = [...nl]; 

Quelques optimisations:

  • Enregistrez la longueur du NodeList dans une variable
  • Définissez explicitement la longueur du nouveau fichier avant le réglage.
  • Accéder aux indices, plutôt que de pousser ou de ne pas modifier.

Code ( jsPerf ):

 var arr = []; for (var i = 0, ref = arr.length = nl.length; i < ref; i++) { arr[i] = nl[i]; } 

Les résultats dépendront complètement du navigateur, pour donner un verdict objectif, nous devons effectuer des tests de performance, voici quelques résultats, vous pouvez les exécuter ici :

Chrome 6:

Firefox 3.6:

Firefox 4.0b2:

Safari 5:

IE9 Platform Preview 3:

Le navigateur le plus rapide et croisé est

 for(var i=-1,l=nl.length;++i!==l;arr[i]=nl[i]); 

Comme je l'ai comparé

http://jsbin.com/oqeda/98/edit

* Merci @CMS pour l'idée!

Chromium (similaire à Google Chrome)FirefoxOpéra

 NodeList.prototype.forEach = Array.prototype.forEach; 

Maintenant, vous pouvez faire document.querySelectorAll ('div'). ForEach (function () …)

Plus rapide et plus court:

 // nl is the nodelist var a=[], l=nl.length>>>0; for( ; l--; a[l]=nl[l] ); 

Découvrez cette publication sur le blog ici qui parle de la même chose. D'après ce que je comprends, le temps supplémentaire pourrait avoir à voir avec la chaîne de la portée.

C'est la fonction que j'utilise dans mon JS:

 function toArray(nl) { for(var a=[], l=nl.length; l--; a[l]=nl[l]); return a; }