Question JavaScript pour ... dans vs pour


Pensez-vous qu'il y a une grande différence pour ... dans et pour les boucles? Quel genre de «pour» préférez-vous utiliser et pourquoi?

Disons que nous avons un tableau de tableaux associatifs:

var myArray = [{'key': 'value'}, {'key': 'value1'}];

On peut donc itérer:

for (var i = 0; i < myArray.length; i++)

Et:

for (var i in myArray)

Je ne vois pas de grande différence. Y a-t-il des problèmes de performance?


445
2017-10-28 10:42


origine


Réponses:


Le choix devrait être basé sur l'idiome qui est le mieux compris.

Un tableau est itéré en utilisant:

for (var i = 0; i < a.length; i++)
   //do stuff with a[i]

Un objet utilisé en tant que tableau associatif est itéré en utilisant:

for (var key in o)
  //do stuff with o[key]

À moins que vous ayez des raisons fulgurantes, restez fidèle à l’usage établi.


539
2017-10-28 11:01



Douglas Crockford recommande dans JavaScript: Les bonnes parties (page 24) pour éviter d’utiliser le for in déclaration.

Si tu utilises for in Pour faire une boucle sur les noms de propriété dans un objet, les résultats ne sont pas triés. Pire: vous pourriez obtenir des résultats inattendus; il inclut les membres hérités de la chaîne prototype et le nom des méthodes.

Tout sauf les propriétés peuvent être filtrés avec .hasOwnProperty. Cet exemple de code fait ce que vous vouliez probablement à l'origine:

for (var name in obj) {
    if (Object.prototype.hasOwnProperty.call(obj, name)) {
        // DO STUFF
    }
}

157
2017-10-28 15:39



FYI - Utilisateurs jQuery


jQuery each(callback) utilisations de la méthode for( ; ; ) boucle par défaut, et utilisera for( in )  seulement si la longueur est undefined.

Par conséquent, je dirais qu'il est prudent de prendre le bon ordre en utilisant cette fonction.

Exemple:

$(['a','b','c']).each(function() {
    alert(this);
});
//Outputs "a" then "b" then "c"

L'inconvénient de l'utilisation de ceci est que si vous faites une logique non UI, vos fonctions seront moins portatives pour d'autres frameworks. le each() fonction est probablement mieux réservé pour une utilisation avec des sélecteurs jQuery et for( ; ; ) pourrait être conseillé autrement.



62
2017-08-04 17:57



il existe des différences de performances en fonction du type de boucle que vous utilisez et de votre navigateur.

Par exemple:

for (var i = myArray.length-1; i >= 0; i--)

est presque deux fois plus rapide sur certains navigateurs que:

for (var i = 0; i < myArray.length; i++)

Cependant, à moins que vos tableaux soient ÉNORMES ou que vous les boucliez constamment, tous sont suffisamment rapides. Je doute sérieusement que le bouclage de tableau soit un goulot d'étranglement dans votre projet (ou pour tout autre projet d'ailleurs)


29
2017-10-28 11:03



Notez que la méthode native Array.forEach est maintenant largement soutenu.


26
2018-06-22 15:59



Mise à jour de la réponse pour 2012 version actuelle de tous les principaux navigateurs - Chrome, Firefox, IE9, Safari et Opera prennent en charge le tableau natif de ES5.forEach.

À moins que vous ayez des raisons de prendre en charge IE8 en mode natif (en gardant à l'esprit que ES5-shim ou Chrome frame peut être fourni à ces utilisateurs, ce qui fournira un environnement JS correct), il est plus simple d'utiliser la syntaxe appropriée du langage:

myArray.forEach(function(item, index) {
    console.log(item, index);
});

La documentation complète pour array.forEach () est à MDN.


24
2018-01-11 21:03



Utiliser forEach pour ignorer la chaîne prototype 

Juste un addendum rapide à La réponse de @ nailer ci-dessus, utiliser forEach avec Object.keys signifie que vous pouvez éviter une itération sur la chaîne prototype sans avoir à utiliser hasOwnProperty.

var Base = function () {
    this.coming = "hey";
};

var Sub = function () {
    this.leaving = "bye";
};

Sub.prototype = new Base();
var tst = new Sub();

for (var i in tst) {
    console.log(tst.hasOwnProperty(i) + i + tst[i]);
}

Object.keys(tst).forEach(function (val) {
    console.log(val + tst[val]);
});

14
2018-03-12 15:14