66 votes

Quel est le meilleur moyen de parcourir un ensemble d'éléments en JavaScript ?

Dans le passé et avec la plupart de mes projets actuels, j'ai tendance à utiliser une boucle for comme ceci :

var elements = document.getElementsByTagName('div');
for (var i=0; i

`

J'ai entendu dire qu'utiliser une boucle "reverse while" est plus rapide mais je n'ai pas de moyen réel de le confirmer :

var elements = document.getElementsByTagName('div'), 
    length = elements.length;

while(length--) {
    doSomething(elements[length]);
}

Quelle est la meilleure pratique en matière de bouclage à travers les éléments en JavaScript, ou n'importe quel tableau d'ailleurs ?

`

7 votes

Ce serait génial si vous marquiez l'une des réponses comme étant répondue. C'est après tout l'un des principaux points de SO :)

1 votes

Ce serait également génial si vous repreniez une réponse acceptée maintenant que celle acceptée est sans valeur >:) . . . d'un autre côté, c'est vraiment ancien donc je m'en fiche vraiment.

67voto

Juan Mendes Points 31678

Voici une belle forme d'une boucle que j'utilise souvent. Vous créez la variable itérée à partir de l'instruction for et vous n'avez pas besoin de vérifier la propriété length, ce qui peut être coûteux surtout lors de l'itération à travers un NodeList. Cependant, vous devez faire attention, vous ne pouvez pas l'utiliser si l'une des valeurs du tableau pourrait être "fausse". En pratique, je ne l'utilise que lorsque je parcours un tableau d'objets qui ne contient pas de valeurs nulles (comme un NodeList). Mais j'adore son sucre syntaxique.

var list = [{a:1,b:2}, {a:3,b:5}, {a:8,b:2}, {a:4,b:1}, {a:0,b:8}];

for (var i=0, item; item = list[i]; i++) {
  // Regardez, pas besoin de faire list[i] dans le corps de la boucle
  console.log("Boucle: index ", i, "élément" + item);
}

Notez que cela peut également être utilisé pour boucler en arrière.

var list = [{a:1,b:2}, {a:3,b:5}, {a:8,b:2}, {a:4,b:1}, {a:0,b:8}];

for (var i = list.length - 1, item; item = list[i]; i--) {
  console.log("Boucle: index ", i, "élément", item);
}

Mise à jour ES6

for...of peut être utilisé pour une syntaxe plus propre. Disponible depuis ES6

const a = ["a", "b", "c"];

for (const [index, element] of a.entries()) {
  console.log({index, element});
}

// Si vous n'avez pas besoin de l'index
for (const element of a) {
  console.log({element});
}

0 votes

Je love ça tellement. Au début, je me demandais comment la boucle allait jamais sortir puis je me suis souvenu que le "milieu" de la déclaration est essentiellement un while et sortira lorsqu'il sera évalué à false. Affecter une variable à un index de tableau qui n'existe pas == false ! Assez intelligent.

5 votes

@sudopeople Juste pour être à 100% précis, lorsque l'élément n'existe pas, il renvoie undefined qui est faux.

1 votes

Dommage, je n'avais pas vu celui-ci! Désolé pour le doublon!

29voto

PhiLho Points 23458

Notez que dans certains cas, vous avez besoin de boucler dans l'ordre inverse (mais vous pouvez aussi utiliser i--).

Par exemple, quelqu'un voulait utiliser la nouvelle fonction getElementsByClassName pour boucler sur les éléments d'une classe donnée et modifier cette classe. Il a constaté que seul un élément sur deux était modifié (dans FF3).
Cela est dû au fait que la fonction renvoie une NodeList en direct, qui reflète donc les changements dans l'arbre Dom. Le fait de parcourir la liste dans l'ordre inverse a permis d'éviter ce problème.

var menus = document.getElementsByClassName("style2");
for (var i = menus.length - 1; i >= 0; i--)
{
  menus[i].className = "style1";
}

En progression d'index croissante, lorsque nous demandons l'index 1, FF inspecte le Dom et saute le premier élément avec style2, qui est le 2ème de l'original Dom, ce qui renvoie donc le 3ème élément initial !

2 votes

Un bon point, bien que je ne conseillerais pas de modifier le nom de la classe en cours d'exécution, car cela oblige le navigateur à recalculer le rendu de l'ensemble du document ...

0 votes

@roenving - Vous pourriez théoriquement copier l'ensemble du document en mémoire, changer ce que vous voulez, et remplacer l'ensemble du document par le nouveau document modifié, mais cela dépend de la situation.

12voto

J'aime faire:

 `var menu = document.getElementsByTagName('div');
for (var i = 0; menu[i]; i++) {
     ...
}` 

Il n'y a pas d'appel à la longueur du tableau à chaque itération.

7voto

À risquer de se faire crier dessus, je prendrais une bibliothèque d'aide JavaScript comme jquery ou prototype elles encapsulent la logique dans de belles méthodes - les deux ont une méthode/itérateur .each pour le faire - et ils s'efforcent tous les deux de le rendre compatible avec tous les navigateurs

ÉDITER: Cette réponse a été postée en 2008. Aujourd'hui, de bien meilleures structures existent. Ce cas particulier pourrait être résolu avec un .forEach.

0 votes

@Hojou - Bien sûr, j'utilise les bibliothèques JavaScript respectives pour de nombreux projets - elles me font gagner du temps et ne me causent pas autant de maux de tête, mais pour certains projets plus petits, je trouve qu'il est préférable d'écrire mes propres méthodes. jQuery est définitivement mon préféré en raison de sa simplicité fantastique!

7 votes

Pourquoi employer une bibliothèque pour effectuer une tâche simple ?-)

2 votes

Je sais, je sais. J'aime juste inclure jQuery pour minimiser le risque d'introduire un problème d'incompatibilité entre navigateurs. Vous n'avez pas besoin de beaucoup de code dans votre 'doSomething' pour introduire l'une de ces erreurs.

7voto

Adam Bellaire Points 42797

Je pense que l'utilisation du premier formulaire est probablement la voie à suivre, car il s'agit probablement de la structure de boucle la plus courante dans l'univers connu, et comme je ne crois pas que la boucle inversée vous fasse gagner du temps en réalité (fait toujours une incrémentation/décrémentation et une comparaison à chaque itération).

Un code reconnaissable et lisible par les autres est certainement une bonne chose.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X