web-dev-qa-db-fra.com

Moyen le plus rapide de convertir une liste de noeuds JavaScript en tableau?

Les questions précédemment répondues ici dit que c'était le moyen le plus rapide:

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

En comparant sur mon navigateur, j'ai constaté qu'il est plus de 3 fois plus lent que cela:

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

Ils produisent tous les deux la même sortie, mais j’ai du mal à croire que ma deuxième version soit la plus rapide possible, d’autant plus que les gens ont dit le contraire ici.

Est-ce une bizarrerie dans mon navigateur (Chrome 6)? Ou y a-t-il un moyen plus rapide?

EDIT: Pour ceux qui s’en soucient, j’ai opté pour le suivant (qui semble être le plus rapide de 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]));
236
jairajs89

Le second a tendance à être plus rapide dans certains navigateurs, mais l’essentiel est que vous deviez l’utiliser car le premier n’est tout simplement pas multi-navigateur. Même si les temps changent

@ kangax ( Aperçu IE 9 )

Array.prototype.slice peut maintenant convertir certains objets de l'hôte (par exemple, NodeList) en tableaux, ce que la majorité des navigateurs modernes ont été en mesure de tandis que.

Exemple:

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

Avec ES6, nous avons maintenant un moyen simple de créer un tableau à partir d'une liste de noeuds: la fonction Array.from() .

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

Voici une nouvelle façon de le faire en utilisant le opérateur de propagation ES6 :

let arr = [...nl];
96
Alexander Olsson

Quelques optimisations:

  • enregistrer la longueur de la liste de noeuds dans une variable
  • explicitement définir la longueur du nouveau tableau avant de définir.
  • accéder aux indices, plutôt que de pousser ou de décaler.

Code ( jsPerf ):

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

Les résultats dépendront complètement du navigateur. Pour donner un verdict objectif, nous devons faire 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:

15
CMS

Le navigateur le plus rapide et le plus polyvalent est

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

Comme j'ai comparé dans

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

* Merci @CMS pour l'idée!

Chromium (Similar to Google Chrome)FirefoxOpera

14
Felipe Buccioni
NodeList.prototype.forEach = Array.prototype.forEach;

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

7
John Williams

plus rapide et plus court:

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

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;
}
3
Web_Designer

Découvrez cet article de blog ici qui parle de la même chose. D'après ce que j'ai compris, le temps supplémentaire pourrait être lié à la progression dans la chaîne du scope.

3
Vivin Paliath

Dans ES6, vous pouvez soit utiliser:

  • Array.from

    let array = Array.from(nodelist)

  • Opérateur de propagation

    let array = [...nodelist]

3
Isabella

Voici les tableaux mis à jour à la date de cette publication (le tableau "plate-forme inconnue" est Internet Explorer 11.15.16299.0):

Safari 11.1.2Firefox 61.0Chrome 68.0.3440.75Internet Explorer 11.15.16299.0

D'après ces résultats, il semble que la méthode de préallocation 1 constitue le pari multi-navigateurs le plus sûr.

1
TomSlick

En supposant que nodeList = document.querySelectorAll("div"), il s’agit d’une forme concise de conversion de nodelist en tableau.

var nodeArray = [].slice.call(nodeList);

See me use ici .

0
Udo E.