1711 votes

Comment boucler un objet JavaScript simple avec les objets comme membres ?

Comment puis-je parcourir en boucle tous les membres d'un objet JavaScript, y compris les valeurs qui sont des objets ?

Par exemple, comment pourrais-je faire une boucle à travers ceci (en accédant à "votre_nom" et "votre_message" pour chacun) ?

var validation_messages = {
    "key_1": {
        "your_name": "jimmy",
        "your_msg": "hello world"
    },
    "key_2": {
        "your_name": "billy",
        "your_msg": "foo equals bar"
    }
}

11 votes

Duplicata possible de Boucle dans un objet JavaScript

2194voto

AgileJon Points 20497
for (var key in validation_messages) {
    // skip loop if the property is from prototype
    if (!validation_messages.hasOwnProperty(key)) continue;

    var obj = validation_messages[key];
    for (var prop in obj) {
        // skip loop if the property is from prototype
        if (!obj.hasOwnProperty(prop)) continue;

        // your code
        alert(prop + " = " + obj[prop]);
    }
}

16 votes

Internet Explorer n'est pas d'accord ( soupir ), indique "Object does not support this property or method" (l'objet ne prend pas en charge cette propriété ou cette méthode) lorsque vous utilisez obj[prop]. Je n'ai pas encore trouvé de solution à ce problème.

3 votes

@MildFuzz en fait, cela a du sens si l'on considère que les objets JS n'ont pas nécessairement de clés numériques. Vous ne pouvez pas simplement itérer dans un objet. Les objets JS for in est très similaire à une foreach .

6 votes

For...in est une bonne solution, mais si vous utilisez des promesses dans la boucle for(), faites attention, car si vous créez une var dans la boucle, vous ne pouvez pas l'utiliser dans la fonction then de la promesse. Votre var dans la boucle n'existe qu'une seule fois, donc il a dans chaque fonction then la même valeur, même la dernière. Si vous avez ce problème, essayez "Object.keys(obj).forEach" ou ma réponse ci-dessous.

847voto

Axel Rauschmayer Points 2401

Sous ECMAScript 5, vous pouvez combiner les éléments suivants Object.keys() et Array.prototype.forEach() :

var obj = {
  first: "John",
  last: "Doe"
};

//
//  Visit non-inherited enumerable keys
//
Object.keys(obj).forEach(function(key) {

  console.log(key, obj[key]);

});

38 votes

+1 pour la brièveté du code mais apparemment, n'est pas aussi efficace qu'un for surprenant. JSPerf - for in vs Object.keys

7 votes

Méfiez-vous de cette erreur en utilisant cette approche : "TypeError : Object.keys appelé sur un non-objet". Le site for ... in ... hasOwnProperty pattern peut être appelé sur n'importe quoi, pour autant que je sache (objet, tableau, null, undefined, true, false, nombre primitif, objets).

2 votes

Notez que IE7 ne prend pas en charge cette fonction.

391voto

Chango Points 4245

Le problème avec cette

for (var key in validation_messages) {
   var obj = validation_messages[key];
   for (var prop in obj) {
      alert(prop + " = " + obj[prop]);
   }
}

c'est que vous allez aussi boucler sur le prototype de l'objet primitif.

Avec celui-ci, vous l'éviterez :

for (var key in validation_messages) {
   if (validation_messages.hasOwnProperty(key)) {
      var obj = validation_messages[key];
      for (var prop in obj) {
         if (obj.hasOwnProperty(prop)) {
            alert(prop + " = " + obj[prop]);
         }
      }
   }
}

47 votes

En bref : contrôle hasOwnProperty à l'intérieur de votre for - in boucles.

62 votes

Notez que cela n'est nécessaire que si votre objet possède des méthodes prototypes. Par exemple, si l'objet que vous parcourez en boucle est simplement un objet JSON, vous n'aurez pas besoin de cette vérification.

7 votes

@rednaw Pour être sûr, j'utilise cette vérification parce que Object.prototype peut être modifié. Aucun script sain ne ferait cela, mais vous ne pouvez pas contrôler quels script pourraient être exécutés dans votre page par des extensions de navigateur folles. Les extensions de navigateur s'exécutent dans votre page (sur la plupart des navigateurs) et elles peuvent causer des problèmes bizarres (par exemple, définir window.setTimeout à null !).

99voto

Tim Santeford Points 10126

Utilisation de Le site Underscore.js _.each :

_.each(validation_messages, function(value, key){
    _.each(value, function(value, key){
        console.log(value);
    });
});

4 votes

Merci Tim, j'utilise l'underscore donc c'est vraiment bien d'avoir une option rapide et propre.

59voto

kennebec Points 33886

Si vous utilisez la récursion, vous pouvez retourner les propriétés de l'objet de n'importe quelle profondeur-

function lookdeep(object){
    var collection= [], index= 0, next, item;
    for(item in object){
        if(object.hasOwnProperty(item)){
            next= object[item];
            if(typeof next== 'object' && next!= null){
                collection[index++]= item +
                ':{ '+ lookdeep(next).join(', ')+'}';
            }
            else collection[index++]= [item+':'+String(next)];
        }
    }
    return collection;
}

//example

var O={
    a:1, b:2, c:{
        c1:3, c2:4, c3:{
            t:true, f:false
        }
    },
    d:11
};
var lookdeepSample= 'O={'+ lookdeep(O).join(',\n')+'}';

/*  returned value: (String)
O={
    a:1, 
    b:2, 
    c:{
        c1:3, c2:4, c3:{
            t:true, f:false
        }
    },
    d:11
}

*/

4 votes

Attention aux boucles, comme appeler ceci sur un noeud DOM.

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