61 votes

Est-ce une mauvaise pratique d'utiliser le même nom de variable dans plusieurs boucles for ?

J'étais juste en train de linting un code JavaScript en utilisant JSHint. Dans le code, j'ai deux boucles for, toutes deux utilisées comme ceci :

for (var i = 0; i < somevalue; i++) { ... }

Les deux boucles for utilisent donc la variable i pour l'itération.

Maintenant, JSHint me montre une erreur pour la deuxième boucle for : "'i' est déjà défini". Je ne peux pas dire que ce n'est pas vrai (car c'est évidemment le cas) mais j'ai toujours pensé que cela n'avait pas d'importance puisque la var i n'est utilisée qu'à cet endroit précis.

Est-ce une mauvaise pratique d'utiliser les boucles for de cette façon ? Devrais-je utiliser une variable différente pour chaque boucle for de mon code, par exemple

//for-loop 1
for (var i = 0; ...; i++) { ... }

//for-loop 2
for (var j = 0; ...; j++) { ... }

Ou est-ce une des erreurs que je peux ignorer (parce que cela ne casse pas mon code, il fait toujours ce qu'il est censé faire) ?

En fait, JSLint arrête de valider à la première boucle for parce que je ne définis pas var i au début de la fonction (c'est pourquoi je suis passé à JSHint en premier lieu). Donc selon l'exemple de cette question : Dois-je utiliser la validation JavaScript JSLint ou JSHint ? - Je devrais utiliser des boucles for comme ça de toute façon pour confirmer JSLint :

...
var i;
...
//for-loop 1
for (i = 0; ...; i++) { ... }
...
//for-loop 2
for (i = 0; ...; i++) { ... }

Cela me semble également bon, car de cette façon je devrais éviter les deux erreurs dans JSLint et JSHint. Mais ce que je ne sais pas, c'est si je dois utiliser une variable différente pour chaque boucle for comme ceci :

...
var i, j;
...
//for-loop 1
for (i = 0; ...; i++) { ... }
//for-loop 2
for (j = 0; ...; j++) { ... }

Existe-t-il une meilleure pratique en la matière ou puis-je choisir l'un des codes ci-dessus, c'est-à-dire choisir "ma" meilleure pratique ?

58voto

James Allardice Points 81162

Comme les déclarations de variables sont hissées au sommet de la portée dans laquelle elles apparaissent, l'interpréteur interprétera effectivement les deux versions de la même manière. Pour cette raison, JSHint et JSLint suggèrent de déplacer les déclarations en dehors de l'initialisateur de boucle.

Le code suivant...

for (var i = 0; i < 10; i++) {}
for (var i = 5; i < 15; i++) {}

... est effectivement interprété comme ceci :

var i;
for (i = 0; i < 10; i++) {}
for (i = 5; i < 15; i++) {}

Remarquez qu'il n'y a réellement qu'une seule déclaration de i Vous ne pouvez pas vraiment "redéclarer" une variable dans la même portée.

Pour répondre à votre question...

Existe-t-il une meilleure pratique pour cela ou puis-je simplement utiliser l'un des codes ci-dessus ?

Les avis divergent sur la meilleure façon de gérer cette situation. Personnellement, je suis d'accord avec JSLint et je pense que le code est plus clair lorsque vous déclarez toutes les variables ensemble au début de chaque scope. Puisque c'est ainsi que le code sera interprété, pourquoi ne pas écrire un code dont l'apparence correspond à son comportement ?

Mais, comme vous l'avez observé, le code fonctionnera quelle que soit l'approche adoptée. Il s'agit donc d'un choix de style/convention, et vous pouvez utiliser la forme qui vous convient le mieux.

6voto

Jashwant Points 10008

Les variables en javascript ont une portée de fonction (et non de bloc).

Lorsque vous définissez var i dans une boucle, elle y reste dans la boucle et aussi dans la fonction ayant cette boucle.

Voir ci-dessous,

function myfun() {
    //for-loop 1
    for (var i = 0; ...; i++) { ... }

    // i is already defined, its scope is visible outside of the loop1.
    // so you should do something like this in second loop.

    for (i = 0; ...; j++) { ... }

    // But doing such will be inappropriate, as you will need to remember
    // if `i` has been defined already or not. If not, the `i` would be global variable.
}

4voto

Corneliu Points 1688

La raison pour laquelle JSHint affiche l'erreur est qu'en JS, la portée des variables est la fonction et les déclarations de variables sont hissées au sommet de la fonction.

Dans Firefox, vous pouvez utiliser let pour définir la portée du bloc, mais il n'est pas actuellement pris en charge par les autres navigateurs.

El let Le mot clé est inclus dans la spécification ECMAScript 6.

4voto

AlexMorley-Finch Points 1498

Je sais que la réponse à cette question a été donnée, mais si vous voulez des super pour les boucles, écrivez-les comme ceci :

var names = ['alex','john','paul','nemo'],
    name = '',
    idx = 0,
    len = name.length;

for(;idx<len;++idx)
{
    name = names[idx];
    // do processing...
}

Il y a plusieurs choses qui se passent ici...

  1. La longueur du tableau est stockée dans len . Cela empêche JS d'évaluer names.length chaque itération

  2. El idx L'incrément est un PRÉ-INCRÉMENT (par exemple, ++idx PAS idx++). Les pré-incréments sont nativement plus rapides que les post-incréments.

  3. La mise en mémoire d'une référence à name . Cette option est facultative mais recommandée si vous utilisez l'option name beaucoup de variables. Chaque appel à names[idx] nécessite de trouver l'index dans le tableau. Que cette recherche soit une recherche linéaire, une recherche arborescente ou une table de hachage, la recherche a toujours lieu. Il faut donc stocker une référence dans une autre variable pour réduire les recherches.

Enfin, il ne s'agit que de ma préférence personnelle, et je n'ai pas de preuve ou d'avantages en termes de performances. Cependant, j'aime toujours initialiser les variables au type qu'elles vont être, par exemple name = '', .

1voto

Nikolay Kostov Points 1241

La meilleure pratique consiste à réduire la portée des variables, ainsi la meilleure façon de déclarer une variable d'itération pour les boucles est la suivante

//for-loop 1
for (var i = 0; ...; i++) { ... }

//for-loop 2
for (var j = 0; ...; j++) { ... }

Je vous remercie pour vos points négatifs, mais je parle de la lisibilité du code :)

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