Les questions précédemment répondues ici indiquaient 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 deux la même sortie, mais j'ai du mal à croire que ma deuxième version est le moyen le plus rapide possible, d'autant plus que les gens ont dit le contraire ici.
Est-ce une bizarrerie dans mon navigateur (Chromium 6)? Ou existe-t-il un moyen 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]));
javascript
arrays
nodelist
jairajs89
la source
la source
arr[arr.length] = nl[i];
peut être plus rapide quearr.push(nl[i]);
cela car il évite un appel de fonction.var i = nl.length, arr = new Array(i); for(; i--; arr[i] = nl[i]);
Réponses:
Le second a tendance à être plus rapide dans certains navigateurs, mais l'essentiel est que vous devez l'utiliser car le premier n'est tout simplement pas multi-navigateur. Même si les temps sont changeants
@kangax ( aperçu IE 9 )
Exemple:
la source
Avec ES6, nous avons maintenant un moyen simple de créer un tableau à partir d'une NodeList: la
Array.from()
fonction.la source
console.log(Array.from([1, 2, 3], x => x + x)); // expected output: Array [2, 4, 6]
Voici une nouvelle façon sympa de le faire en utilisant l' opérateur de propagation ES6 :
la source
ERROR TypeError: el.querySelectorAll(...).slice is not a function
Quelques optimisations:
Code ( jsPerf ):
la source
Les résultats dépendront complètement du navigateur, pour donner un verdict objectif, nous devons faire des tests de performances, voici quelques résultats, vous pouvez les exécuter ici :
Chrome 6:
Firefox 3.6:
Firefox 4.0b2:
Safari 5:
Aperçu de la plateforme IE9 3:
la source
for (var i=o.length; i--;)
... la "boucle" de ces tests a-t-elle réévalué la propriété length à chaque itération?Le navigateur le plus rapide et le plus croisé est
Comme je l'ai comparé dans
http://jsbin.com/oqeda/98/edit
* Merci @CMS pour l'idée!
la source
Dans ES6, vous pouvez utiliser:
Array.from
let array = Array.from(nodelist)
Opérateur de diffusion
let array = [...nodelist]
la source
Vous pouvez maintenant faire document.querySelectorAll ('div'). ForEach (function () ...)
la source
NodeList
ne fonctionne pas maisObject
est:Object.prototype.forEach = Array.prototype.forEach; document.getElementsByTagName("img").forEach(function(img) { alert(img.src); });
plus rapide et plus court:
la source
>>>0
? Et pourquoi ne pas mettre les affectations sur la première partie de la boucle for?l
est0
, la boucle se terminera, donc le0
e élément ne sera pas copié (rappelez-vous qu'il y a un élément à l'index0
)>>>
peut ne pas être nécessaire ici mais est utilisé pour garantir que la longueur de la liste de nodules adhère aux spécifications du tableau; il garantit qu'il s'agit d'un entier 32 bits non signé. Vérifiez-le ici ecma-international.org/ecma-262/5.1/#sec-15.4 Si vous aimez le code illisible, utilisez cette méthode avec les suggestions de @ CamiloMartin!var
à l'intérieur la première partie d'unefor
boucle à cause du «levage variable». La déclaration devar
sera «hissée» en haut de la fonction, même si lavar
ligne apparaît quelque part plus bas, ce qui peut provoquer des effets secondaires qui ne sont pas évidents dans la séquence de code. Par exemple un code dans la même fonction se produisant avant la boucle pourrait dépendre dea
etl
étant non déclarés. Par conséquent, pour une meilleure prévisibilité, déclarez vos vars en haut de la fonction (ou si sur ES6, utilisezconst
ou à lalet
place, qui ne sont pas hissés).Consultez cet article de 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 montée de la chaîne de portée.
la source
Array.prototype.slice
soit dépendant du navigateur. Je me demande quel algorithme chacun des navigateurs utilise.C'est la fonction que j'utilise dans mon JS:
la source
Voici les graphiques mis à jour à la date de cette publication (le graphique "plate-forme inconnue" est Internet Explorer 11.15.16299.0):
D'après ces résultats, il semble que la méthode de préallocation 1 soit le pari multi-navigateur le plus sûr.
la source
En supposant
nodeList = document.querySelectorAll("div")
qu'il s'agit d'une forme concise de conversionnodelist
en tableau.Voyez-moi l'utiliser ici .
la source