web-dev-qa-db-fra.com

Pourquoi utiliser "for ... in" avec une itération de tableau est-il une mauvaise idée?

On m'a dit de ne pas utiliser for...in avec des tableaux en JavaScript. Pourquoi pas?

1621
lYriCAlsSH

La raison en est que l'on construit:

var a = []; // Create a new empty array.
a[5] = 5;   // Perfectly legal JavaScript that resizes the array.

for (var i = 0; i < a.length; i++) {
    // Iterate over numeric indexes from 0 to 5, as everyone expects.
    console.log(a[i]);
}

/* Will display:
   undefined
   undefined
   undefined
   undefined
   undefined
   5
*/

peut parfois être totalement différent de l'autre:

var a = [];
a[5] = 5;
for (var x in a) {
    // Shows only the explicitly set index of "5", and ignores 0-4
    console.log(x);
}

/* Will display:
   5
*/

Considérez également que JavaScript les bibliothèques peuvent faire ce genre de chose, ce qui affectera tout tableau que vous créez:

// Somewhere deep in your JavaScript library...
Array.prototype.foo = 1;

// Now you have no idea what the below code will do.
var a = [1, 2, 3, 4, 5];
for (var x in a){
    // Now foo is a part of EVERY array and 
    // will show up here as a value of 'x'.
    console.log(x);
}

/* Will display:
   0
   1
   2
   3
   4
   foo
*/

1427
Triptych

L'instruction for-in en elle-même n'est pas une "mauvaise pratique", mais il peut s'agir de mal utilisé, par exemple, de iterate sur des tableaux ou des objets de type tableau.

Le but de l'instruction for-in est de enumerate sur les propriétés de l'objet. Cette déclaration va remonter dans la chaîne de prototypes, énumérant également les propriétés inherited, une chose que parfois n'est pas souhaitée.

De plus, l'ordre des itérations n'est pas garanti par la spéc., Ce qui signifie que si vous voulez "itérer" un objet de tableau, vous ne pouvez pas être sûr avec cette instruction que les propriétés (index de tableau) seront visitées dans l'ordre numérique.

Par exemple, dans JScript (IE <= 8), l'ordre d'énumération, même pour les objets Array, est défini lors de la création des propriétés:

var array = [];
array[2] = 'c';
array[1] = 'b';
array[0] = 'a';

for (var p in array) {
  //... p will be "2", "1" and "0" on IE
}

En outre, en ce qui concerne les propriétés héritées, si vous étendez par exemple l'objet Array.prototype (comme certaines bibliothèques comme le fait MooTools), ces propriétés seront également énumérées:

Array.prototype.last = function () { return this[this.length-1]; };

for (var p in []) { // an empty array
  // last will be enumerated
}

Comme je l'ai déjà dit pour iterate sur des tableaux ou des objets semblables à des tableaux, la meilleure chose à faire est d'utiliser une boucle séquentielle, telle qu'une boucle forwhile en clair.

Lorsque vous souhaitez énumérer uniquement les propriétés _/own d'un objet (celles qui ne sont pas héritées), vous pouvez utiliser la méthode hasOwnProperty:

for (var prop in obj) {
  if (obj.hasOwnProperty(prop)) {
    // prop is not inherited
  }
}

Et certaines personnes recommandent même d'appeler la méthode directement à partir de Object.prototype pour éviter les problèmes si quelqu'un ajoute une propriété nommée hasOwnProperty à notre objet:

for (var prop in obj) {
  if (Object.prototype.hasOwnProperty.call(obj, prop)) {
    // prop is not inherited
  }
}
364
CMS

Il y a trois raisons pour lesquelles vous ne devriez pas utiliser for..in pour itérer sur des éléments de tableau:

  • for..in va parcourir toutes les propriétés propres et héritées de l'objet tableau qui ne sont pas DontEnum; cela signifie que si quelqu'un ajoute des propriétés à l'objet de tableau spécifique (il y a des raisons valables à cela - je l'ai fait moi-même) ou change de Array.prototype (ce qui est considéré comme une mauvaise pratique dans le code censé fonctionner avec d'autres scripts), ces propriétés sera itéré aussi bien; Les propriétés héritées peuvent être exclues en vérifiant hasOwnProperty(), mais cela ne vous aidera pas avec les propriétés définies dans l'objet tableau lui-même.

  • for..in n'est pas garanti pour préserver l'ordre des éléments

  • il est lent car il faut parcourir toutes les propriétés de l'objet tableau et de sa chaîne de prototypes et obtenir uniquement le nom de la propriété, c'est-à-dire que pour obtenir la valeur, une recherche supplémentaire sera nécessaire

107
Christoph

Car for ... in énumère à travers l'objet qui contient le tableau, pas le tableau lui-même. Si j'ajoute une fonction à la chaîne de prototypes de tableaux, elle sera également incluse. C'est à dire.

Array.prototype.myOwnFunction = function() { alert(this); }
a = new Array();
a[0] = 'foo';
a[1] = 'bar';
for(x in a){
 document.write(x + ' = ' + a[x]);
}

Cela va écrire:

 0 = foo 
 1 = barre 
 MyOwnFunction = function () {alert (this); } 

Et comme vous ne pouvez jamais être sûr que rien ne sera ajouté à la chaîne de prototypes, utilisez simplement une boucle for pour énumérer le tableau:

for(i=0,x=a.length;i<x;i++){
 document.write(i + ' = ' + a[i]);
}

Cela va écrire:

 0 = foo 
 1 = bar 
50
Pim Jager

Dans l'isolement, l'utilisation de for-in sur des tableaux n'a rien d'anormal. For-in itère sur les noms de propriétés d'un objet et, dans le cas d'un tableau "prêt à l'emploi", les propriétés correspondent aux index du tableau. (Les propriétés intégrées telles que length, toString et ainsi de suite ne sont pas incluses dans l'itération.)

Toutefois, si votre code (ou la structure que vous utilisez) ajoute des propriétés personnalisées aux tableaux ou au prototype de tableau, ces propriétés seront incluses dans l'itération, ce qui n'est probablement pas ce que vous souhaitez.

Certains frameworks JS, tels que Prototype modifie le prototype Array. D'autres frameworks, comme JQuery, ne le permettent pas. Vous pouvez donc utiliser JQuery en toute sécurité.

Si vous avez des doutes, vous ne devriez probablement pas utiliser le for-in. 

Une autre façon de parcourir un tableau consiste à utiliser une boucle for:

for (var ix=0;ix<arr.length;ix++) alert(ix);

Cependant, cela a un problème différent. Le problème est qu'un tableau JavaScript peut avoir des "trous". Si vous définissez arr comme:

var arr = ["hello"];
arr[100] = "goodbye";

Ensuite, le tableau a deux éléments, mais une longueur de 101. L'utilisation de for-in donnera deux index, tandis que la boucle for donnera 101 index, où 99 a la valeur undefined.

38
JacquesB

En plus des raisons données dans d'autres réponses, vous pouvez ne pas vouloir utiliser la structure "for ... in" si vous devez faire des calculs avec la variable counter car la boucle itère à travers les noms des propriétés de l'objet et donc la variable est une ficelle.

Par exemple,

for (var i=0; i<a.length; i++) {
    document.write(i + ', ' + typeof i + ', ' + i+1);
}

écrirai 

0, number, 1
1, number, 2
...

tandis que,

for (var ii in a) {
    document.write(i + ', ' + typeof i + ', ' + i+1);
}

écrirai

0, string, 01
1, string, 11
...

Bien sûr, cela peut facilement être surmonté en incluant

ii = parseInt(ii);

dans la boucle, mais la première structure est plus directe.

30
ctmiddle

Depuis 2016 (ES6), nous pouvons utiliser for…of pour l'itération de tableau, comme John Slegers l'a déjà remarqué. 

Je voudrais juste ajouter ce code de démonstration simple, pour rendre les choses plus claires:

Array.prototype.foo = 1;
var arr = [];
arr[5] = "xyz";

console.log("for...of:");
var count = 0;
for (var item of arr) {
    console.log(count + ":", item);
    count++;
    }

console.log("for...in:");
count = 0;
for (var item in arr) {
    console.log(count + ":", item);
    count++;
    }

La console affiche:

for...of:

0: undefined
1: undefined
2: undefined
3: undefined
4: undefined
5: xyz

for...in:

0: 5
1: foo

En d'autres termes:

  • for...of compte de 0 à 5 et ignore également Array.prototype.foo. Il montre un tableau valeurs .

  • for...in répertorie uniquement le 5, en ignorant les index de tableau non définis, mais en ajoutant foo. Il montre un tableau noms de propriétés .

29
MarcG

Outre le fait que for...in parcourt toutes les propriétés énumérables (ce qui est pas identique à "tous les éléments du tableau"!), Voir http://www.ecma-international.org /publications/files/ECMA-ST/Ecma-262.pdf , section 12.6.4 (5ème édition) ou 13.7.5.15 (7ème édition):

La mécanique et l'ordre d'énumération des propriétés ... n'est pas spécifié ...

(Souligné par moi.)

Cela signifie que si un navigateur le souhaite, il peut parcourir les propriétés dans l’ordre dans lequel elles ont été insérées. Ou dans l'ordre numérique. Ou dans l'ordre lexical (où "30" précède "4"! N'oubliez pas que toutes les clés d'objet - et donc tous les index de tableaux - sont en fait des chaînes, ce qui est parfaitement logique). Il pourrait les parcourir par compartiment s'il implémentait des objets sous forme de tables de hachage. Ou bien prenez n'importe quoi et ajoutez "à l'envers". Un navigateur peut même itérer au hasard et être conforme à la norme ECMA-262, à condition de ne visiter qu'une seule fois chaque propriété.

En pratique, la plupart des navigateurs aimeraient itérer à peu près dans le même ordre. Mais rien ne dit qu'ils doivent le faire. Cela dépend de la mise en œuvre et peut changer à tout moment si une autre méthode s'avère beaucoup plus efficace.

Quoi qu'il en soit, for...in n'a aucune connotation d'ordre. Si vous tenez à l'ordre, soyez explicite à ce sujet et utilisez une boucle for régulière avec un index.

22
cHao

Réponse courte: ça ne vaut tout simplement pas la peine.


Réponse plus longue: Cela ne vaut tout simplement pas la peine, même si l'ordre séquentiel des éléments et les performances optimales ne sont pas nécessaires.


Réponse longue: Cela ne vaut tout simplement pas la peine, pour les raisons suivantes:

  • L'utilisation de for (var i in array) {} entraînera l'interprétation de 'tableau' comme d'un autre objet pure, traversant la chaîne de propriétés de l'objet et s'exécutant plus lentement qu'une boucle for basée sur l'index.
  • Il n'est pas garanti de renvoyer les propriétés de l'objet dans un ordre séquentiel comme on pourrait s'y attendre.
  • L'utilisation des vérifications hasOwnProperty() ou isNaN() pour filtrer les propriétés de l'objet est un temps système supplémentaire, ce qui le ralentit (encore plus). En outre, l’introduction d’une telle logique supplémentaire annule la raison principale de son utilisation, c’est-à-dire du format plus concis.

Pour ces raisons, un compromis acceptable entre performance et commodité n'existe même pas. En réalité, il n'y a aucun avantage à moins que l'intention soit de traiter le tableau comme un objet pure et d'effectuer des opérations sur les propriétés de l'objet tableau.

21
WynandB

Parce qu'il énumère à travers des champs d'objet, pas des index. Vous pouvez obtenir de la valeur avec l'index "length" et je doute que vous vouliez cela.

15
vava

Principalement deux raisons:

Un

Comme d'autres l'ont dit, vous pourriez obtenir des clés qui ne sont pas dans votre tableau ou qui sont héritées du prototype. Donc, si, disons, une bibliothèque ajoute une propriété aux prototypes Array ou Object:

Array.prototype.someProperty = true

Vous l'obtiendrez dans chaque tableau:

for(var item in [1,2,3]){
  console.log(item) // will log 1,2,3 but also "someProperty"
}

vous pouvez résoudre ceci avec la méthode hasOwnProperty:

var ary = [1,2,3];
for(var item in ary){
   if(ary.hasOwnProperty(item)){
      console.log(item) // will log only 1,2,3
   }
}

mais cela est vrai pour itérer sur n'importe quel objet avec une boucle for-in.

Deux

L'ordre des éléments d'un tableau est généralement important, mais la boucle for-in ne va pas nécessairement itérer dans le bon ordre, car elle traite le tableau comme un objet, c'est-à-dire la manière dont il est implémenté dans JS comme un tableau . Cela semble être une petite chose, mais il peut vraiment bousiller les applications et est difficile à déboguer.

15
Lior

Le problème avec for ... in ... - et cela ne devient un problème que lorsqu'un programmeur ne comprend pas vraiment la langue; ce n'est pas vraiment un bug ou quoi que ce soit - c'est qu'il itère sur tous membres d'un objet (enfin, tous les énumérables membres, mais c'est un détail pour l'instant). Lorsque vous souhaitez parcourir seulement les propriétés indexées d'un tableau, le seul moyen garanti de conserver la cohérence sémantique consiste à utiliser un index entier (c'est-à-dire une boucle de style for (var i = 0; i < array.length; ++i)).

Tout objet peut être associé à des propriétés arbitraires. Il n'y aurait rien de terrible à charger des propriétés supplémentaires sur une instance de tableau, en particulier. Le code qui veut voir uniquement propriétés indexées de type tableau indexé donc doit s'en tenir à un index entier. Code qui est parfaitement au courant de ce que for ... in fait et qui est vraiment besoin pour voir toutes les propriétés, eh bien c'est bien aussi.

14
Pointy

Je ne pense pas avoir grand chose à ajouter, par exemple. Réponse de Triptych ou Réponse de CMS sur la raison pour laquelle l'utilisation de for-in devrait être évitée dans certains cas.

Je voudrais cependant ajouter que dans les navigateurs modernes, il existe une alternative à for-in qui peut être utilisée dans les cas où for-in ne peut pas être utilisé. Cette alternative est for-of :

for (var item of items) {
    console.log(item);
}

Remarque :

Malheureusement, aucune version d'Internet Explorer ne prend en charge cette fonctionnalité ( Edge 12+ ne), vous devrez donc attendre un peu plus longtemps pour pouvoir l'utiliser dans votre code de production côté client. Toutefois, vous devriez utiliser le code JS côté serveur de manière sûre (si vous utilisez Node.js ).

10
John Slegers

De plus, en raison de la sémantique, la manière dont for, in traite les tableaux (c'est-à-dire comme tout autre objet JavaScript) n'est pas alignée sur les autres langages populaires.

// C#
char[] a = new char[] {'A', 'B', 'C'};
foreach (char x in a) System.Console.Write(x); //Output: "ABC"

// Java
char[] a = {'A', 'B', 'C'};
for (char x : a) System.out.print(x);          //Output: "ABC"

// PHP
$a = array('A', 'B', 'C');
foreach ($a as $x) echo $x;                    //Output: "ABC"

// JavaScript
var a = ['A', 'B', 'C'];
for (var x in a) document.write(x);            //Output: "012"
8
matpop

Outre les autres problèmes, la syntaxe "for..in" est probablement plus lente, car l'index est une chaîne, pas un entier.

var a = ["a"]
for (var i in a)
    alert(typeof i)  // 'string'
for (var i = 0; i < a.length; i++)
    alert(typeof i)  // 'number'
7
dc1

Un aspect important est que for...in itère uniquement les propriétés contenues dans un objet dont l'attribut enumerable property est défini sur true. Donc, si on tente d'itérer sur un objet en utilisant for...in, des propriétés arbitraires peuvent être manquées si leur attribut de propriété énumérable est false. Il est tout à fait possible de modifier l'attribut de propriété énumérable pour les objets Array normaux afin que certains éléments ne soient pas énumérés. Bien qu'en général, les attributs de propriété ont tendance à s'appliquer aux propriétés de fonction dans un objet.

On peut vérifier la valeur de l'attribut de propriété énumérable d'une propriété par:

myobject.propertyIsEnumerable('myproperty')

Ou pour obtenir les quatre attributs de propriété:

Object.getOwnPropertyDescriptor(myobject,'myproperty')

C'est une fonctionnalité disponible dans ECMAScript 5 - dans les versions précédentes, il n'était pas possible de modifier la valeur de l'attribut de propriété énumérable (elle était toujours définie sur true).

7
Pierz

La for/in fonctionne avec deux types de variables: les tables de hachage (tableaux associatifs) et le tableau (non associatif).

JavaScript déterminera automatiquement la manière dont il passe à travers les éléments. Ainsi, si vous savez que votre tableau est vraiment non associatif, vous pouvez utiliser for (var i=0; i<=arrayLen; i++) et ignorer l'itération de détection automatique.

Mais à mon avis, il vaut mieux utiliser for/in, le processus requis pour cette détection automatique est très petit. 

La réponse réelle dépendra de la manière dont le navigateur analysera/interprétera le code JavaScript. Cela peut changer entre les navigateurs.

Je ne peux penser à aucun autre but pour ne pas utiliser for/in;

//Non-associative
var arr = ['a', 'b', 'c'];
for (var i in arr)
   alert(arr[i]);

//Associative
var arr = {
   item1 : 'a',
   item2 : 'b',
   item3 : 'c'
};

for (var i in arr)
   alert(arr[i]);
7
Ricardo

TL & DR: Utiliser la boucle for in dans les tableaux n'est pas mauvais, bien au contraire.

Je pense que la boucle for in est une gemme de JS si elle est utilisée correctement dans les tableaux. Vous êtes censé avoir le plein contrôle de votre logiciel et savoir ce que vous faites. Voyons les inconvénients mentionnés et réfutons-les un à un.

  1. Il parcourt également les propriétés héritées: Tout d'abord, toute extension du Array.prototype aurait dû être réalisée à l'aide de Object.defineProperty() et leur descripteur enumerable devrait être défini sur false. Toute bibliothèque ne le faisant pas ne devrait pas être utilisée du tout.
  2. Les propriétés que vous ajoutez ultérieurement à la chaîne d'héritage sont comptées: Lors de la sous-classification de tableaux par Object.setPrototypeOf ou par classe extend. Vous devez à nouveau utiliser Object.defineProperty() qui définit par défaut les descripteurs de propriétés writable, enumerable et configurable sur false. Voyons un exemple de sous-classement de tableau ici ...

function Stack(...a){
  var stack = new Array(...a);
  Object.setPrototypeOf(stack, Stack.prototype);
  return stack;
}
Stack.prototype = Object.create(Array.prototype);                                 // now stack has full access to array methods.
Object.defineProperty(Stack.prototype,"constructor",{value:Stack});               // now Stack is a proper constructor
Object.defineProperty(Stack.prototype,"peak",{value: function(){                  // add Stack "only" methods to the Stack.prototype.
                                                       return this[this.length-1];
                                                     }
                                             });
var s = new Stack(1,2,3,4,1);
console.log(s.peak());
s[s.length] = 7;
console.log("length:",s.length);
s.Push(42);
console.log(JSON.stringify(s));
console.log("length:",s.length);

for(var i in s) console.log(s[i]);

Donc, vous voyez .. La boucle for in est maintenant sûre puisque vous vous souciez de votre code.

  1. La boucle for in est lente: Hell no. C'est de loin la méthode d'itération la plus rapide si vous passez en boucle sur des tableaux épars qui sont nécessaires de temps en temps. C'est l'une des astuces de performance les plus importantes à connaître. Voyons un exemple. Nous allons passer en boucle sur un tableau fragmenté.

var a = [];
a[0] = "zero";
a[10000000] = "ten million";
console.time("for loop on array a:");
for(var i=0; i < a.length; i++) a[i] && console.log(a[i]);
console.timeEnd("for loop on array a:");
console.time("for in loop on array a:");
for(var i in a) a[i] && console.log(a[i]);
console.timeEnd("for in loop on array a:");

7
Redu

Parce que cela va itérer sur les propriétés appartenant aux objets dans la chaîne de prototypes si vous ne faites pas attention.

Vous pouvez utiliser for.. in, assurez-vous simplement de vérifier chaque propriété avec hasOwnProperty .

6
JAL

Ce n'est pas nécessairement mauvais (selon ce que vous faites), mais dans le cas des tableaux, si quelque chose a été ajouté à Array.prototype, vous obtiendrez des résultats étranges. Où vous vous attendez à ce que cette boucle s'exécute trois fois:

var arr = ['a','b','c'];
for (var key in arr) { ... }

Si une fonction appelée helpfulUtilityMethod a été ajoutée à Array's prototype, votre boucle s'exécutera quatre fois: key serait 0, 1, 2 et helpfulUtilityMethod. Si vous attendiez seulement des entiers, oups.

5
josh3736

Utilisez for(var x in y) uniquement sur les listes de propriétés, pas sur les objets (comme expliqué ci-dessus).

5
user268396

L'utilisation de la boucle for...in pour un tableau n'est pas fausse, bien que je puisse deviner pourquoi quelqu'un vous a dit ceci:

1.) Il existe déjà une fonction ou une méthode d'ordre supérieur qui a cet objectif pour un tableau, mais qui a plus de fonctionnalités et une syntaxe plus claire, appelée 'forEach': Array.prototype.forEach(function(element, index, array) {} );

2.) Les tableaux ont toujours une longueur, mais for...in et forEach n'exécutent aucune fonction pour aucune valeur qui est 'undefined', mais uniquement pour les index pour lesquels une valeur est définie. Donc, si vous n'attribuez qu'une seule valeur, ces boucles n'exécuteront une fonction qu'une seule fois, mais comme un tableau est énuméré, sa longueur sera toujours égale à l'index le plus élevé ayant une valeur définie, mais cette longueur risque de passer inaperçue lors de l'utilisation de ces éléments. boucles.

3.) La boucle standard pour exécuter une fonction autant de fois que vous définissez dans les paramètres, et puisqu'un tableau est numéroté, il est plus logique de définir combien de fois vous voulez exécuter une fonction. Contrairement aux autres boucles, la boucle for peut ensuite exécuter une fonction pour chaque index du tableau, que la valeur soit définie ou non.

En substance, vous pouvez utiliser n’importe quelle boucle, mais vous devez vous rappeler exactement comment elles fonctionnent. Comprendre les conditions de réitération des différentes boucles, leurs fonctionnalités distinctes et se rendre compte qu'elles seront plus ou moins appropriées pour différents scénarios. 

En outre, il peut être considéré comme une meilleure pratique d’utiliser la méthode forEach que la boucle for...in en général, car il est plus facile d’écrire et a plus de fonctionnalités. Vous voudrez peut-être donc avoir l’habitude de n'utiliser que cette méthode et cette norme pour, mais votre appel.

Voir ci-dessous que les deux premières boucles n'exécutent les instructions console.log qu'une seule fois, tandis que la boucle standard pour exécute la fonction autant de fois que spécifié, dans ce cas, array.length = 6.

var arr = [];
arr[5] = 'F';

for (var index in arr) {
console.log(index);
console.log(arr[index]);
console.log(arr)
}
// 5
// 'F'
// => (6) [undefined x 5, 6]

arr.forEach(function(element, index, arr) {
console.log(index);
console.log(element);
console.log(arr);
});
// 5
// 'F'
// => Array (6) [undefined x 5, 6]

for (var index = 0; index < arr.length; index++) {
console.log(index);
console.log(arr[index]);
console.log(arr);
};
// 0
// undefined
// => Array (6) [undefined x 5, 6]

// 1
// undefined
// => Array (6) [undefined x 5, 6]

// 2
// undefined
// => Array (6) [undefined x 5, 6]

// 3
// undefined
// => Array (6) [undefined x 5, 6]

// 4
// undefined
// => Array (6) [undefined x 5, 6]

// 5
// 'F'
// => Array (6) [undefined x 5, 6]
3
mrmaclean89

Une boucle for ... in énumère toujours les clés . Les clés des propriétés des objets sont toujours String, même les propriétés indexées d'un tableau:

var myArray = ['a', 'b', 'c', 'd'];
var total = 0
for (elem in myArray) {
  total += elem
}
console.log(total); // 00123
2
Maher Tliba

Voici les raisons pour lesquelles c'est (généralement) une mauvaise pratique:

  1. Les boucles for...in parcourent toutes leurs propriétés énumérables propres et les propriétés énumérables de leur (s) prototype (s). Habituellement, dans une itération de tableau, nous voulons seulement itérer sur le tableau lui-même. Et même si vous ne souhaitez rien ajouter au tableau, vos bibliothèques ou votre framework peuvent ajouter quelque chose.

Exemple:

Array.prototype.hithere = 'hithere';

var array = [1, 2, 3];
for (let el in array){
    // the hithere property will also be iterated over
    console.log(el);
}
  1. for...in boucles ne garantit pas un ordre d'itération spécifique. Bien que cet ordre soit généralement utilisé dans la plupart des navigateurs modernes de nos jours, il n’existe toujours pas de garantie à 100%.
  2. Les boucles for...in ignorent les éléments de tableau undefined, c'est-à-dire les éléments de tableau qui n'ont pas encore été attribués.

Exemple::

const arr = []; 
arr[3] = 'foo';   // resize the array to 4
arr[4] = undefined; // add another element with value undefined to it

// iterate over the array, a for loop does show the undefined elements
for (let i = 0; i < arr.length; i++) {
    console.log(arr[i]);
}

console.log('\n');

// for in does ignore the undefined elements
for (let el in arr) {
    console.log(arr[el]);
}
2

for ... in est utile pour travailler sur un objet en JavaScript, mais pas pour un tableau, mais nous ne pouvons toujours pas dire que c'est une mauvaise façon, mais ce n'est pas recommandé, regardez cet exemple ci-dessous en utilisant for ... in loop:

let txt = "";
const person = {fname:"Alireza", lname:"Dezfoolian", age:35}; 
for (const x in person) {
    txt += person[x] + " ";
}
console.log(txt); //Alireza Dezfoolian 35 

OK, faisons-le avec Array maintenant:

let txt = "";
const person = ["Alireza", "Dezfoolian", 35]; 
for (const x in person) {
   txt += person[x] + " ";
}
console.log(txt); //Alireza Dezfoolian 35 

Comme vous voyez le résultat le même ...

Mais essayons quelque chose, faisons un prototype de quelque chose à Array...

Array.prototype.someoneelse = "someoneelse";

Maintenant, nous créons un nouveau tableau ();

let txt = "";
const arr = new Array();
arr[0] = 'Alireza';
arr[1] = 'Dezfoolian';
arr[2] = 35;
for(x in arr) {
 txt += arr[x] + " ";
}
console.log(txt); //Alireza Dezfoolian 35 someoneelse

Vous voyez le oneelse !!! ... En fait, nous parcourons un nouvel objet Array dans ce cas!

C'est donc l'une des raisons pour lesquelles nous devons utiliser for..in avec précaution, mais ce n'est pas toujours le cas ...

1
Alireza

Les éléments JavaScript étant enregistrés en tant que propriétés d'objet standard, il Il est déconseillé de parcourir les tableaux JavaScript en utilisant ... in boucles car les éléments normaux et toutes les propriétés énumérables seront énumérés.

De https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Indexed_collections

0
Badr Elmers

bien que cela ne soit pas spécifiquement abordé par cette question, j'ajouterais qu'il existe une très bonne raison de ne jamais utiliser pour ... dans avec un NodeList (comme on obtiendrait à partir d'un appel querySelectorAll, car il ne voit pas du tout les éléments retournés , à la place, il ne parcourt que les propriétés NodeList.

dans le cas d'un seul résultat, j'ai eu:

var nodes = document.querySelectorAll(selector);
nodes
▶ NodeList [a._19eb]
for (node in nodes) {console.log(node)};
VM505:1 0
VM505:1 length
VM505:1 item
VM505:1 entries
VM505:1 forEach
VM505:1 keys
VM505:1 values

ce qui explique pourquoi ma for (node in nodes) node.href = newLink; échouait.

0
jcomeau_ictx