Question Comment faire une boucle sur un objet JavaScript brut avec les objets en tant que membres?


Comment puis-je faire une boucle sur tous les membres d'un objet JavaScript, y compris les valeurs qui sont des objets.

Par exemple, comment pourrais-je passer en revue ceci (en accédant aux "your_name" et "your_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"
    }
}

1243
2018-05-28 16:18


origine


Réponses:


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]);
    }
}

1797
2018-05-28 16:20



Sous ECMAScript 5, vous pouvez combiner 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]);

});


564
2018-04-20 22:04



Le problème avec ça

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

c'est que vous traverserez également 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]);
         }
      }
   }
}

363
2018-05-19 20:58



Dans ES6 vous pouvez traverser un objet comme celui-ci: (en utilisant fonction de flèche)

Object.keys(myObj).forEach(key => {
    console.log(key);          // the name of the current key.
    console.log(myObj[key]);   // the value of the current key.
});

jsbin

Dans ES7 vous pouvez utiliser Object.entries au lieu de Object.keys et boucle à travers un objet comme celui-ci:

Object.entries(myObj).forEach(([key, val]) => {
    console.log(key);          // the name of the current key.
    console.log(val);          // the value of the current key.
});

Ce qui précède fonctionnerait également comme bon mot:

Object.keys(myObj).forEach(key => console.log(key, myObj[key]));

jsbin

Dans le cas où vous souhaitez également parcourir des objets imbriqués, vous pouvez utiliser un récursif fonction (ES6):

const loopNestedObj = (obj) => {
  Object.keys(obj).forEach(key => {
    if (obj[key] && typeof obj[key] === 'object') loopNestedObj(obj[key]);  // recurse.
    else console.log(key, obj[key]);  // or do something with key and val.
  });
};

jsbin

Identique à la fonction ci-dessus, mais avec ES7 Object.entries au lieu de Object.keys:

const loopNestedObj = (obj) => {
  Object.entries(obj).forEach(([key, val]) => {
    if (val && typeof val === 'object') loopNestedObj(val);  // recurse.
    else console.log(key, val);  // or do something with key and val.
  });
};

Si vous êtes dans programmation fonctionnelle vous pouvez utiliser Object.keys/Object.entries pour énumérer l'objet, puis traiter les valeurs et ensuite utiliser reduce() pour revenir à un nouvel objet.

const loopNestedObj = (obj) => 
  Object.keys(obj)
    // Use .filter(), .map(), etc. if you need.
    .reduce((newObj, key) => 
      (obj[key] && typeof obj[key] === 'object') ?
        {...newObj, [key]: loopNestedObj(obj[key])} :  // recurse.
        {...newObj, [key]: obj[key]},                  // Define value.
      {});

142
2018-01-09 14:22



En utilisant Underscore.js _.each:

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

93
2017-09-16 12:11



Si vous utilisez la récursivité, vous pouvez renvoyer des propriétés d'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
}

*/

52
2018-05-28 18:03



Je sais que c'est tard, mais il m'a fallu 2 minutes pour écrire cette version optimisée et améliorée de la réponse d'AgileJon:

var key, obj, prop, owns = Object.prototype.hasOwnProperty;

for (key in validation_messages ) {

    if (owns.call(validation_messages, key)) {

        obj = validation_messages[key];

        for (prop in obj ) {

            // using obj.hasOwnProperty might cause you headache if there is
            // obj.hasOwnProperty = function(){return false;}
            // but owns will always work 
            if (owns.call(obj, prop)) {
                console.log(prop, "=", obj[prop]);
            }

        }

    }

}

29
2017-09-05 06:17



for(var k in validation_messages) {
    var o = validation_messages[k];
    do_something_with(o.your_name);
    do_something_else_with(o.your_msg);
}

27
2018-05-28 16:20