Jak zapętlić zwykły obiekt JavaScript z obiektami jako członkami?

Jak mogę zapętlić wszystkie elementy w obiekcie JavaScript, w tym wartości, które są obiektami.

Na przykład, Jak mogę przejść przez to (dostęp do "your_name" i "your_message"dla każdego)?

var validation_messages = {
    "key_1": {
        "your_name": "jimmy",
        "your_msg": "hello world"
    },
    "key_2": {
        "your_name": "billy",
        "your_msg": "foo equals bar"
    }
}
 1291
Author: Script47, 2009-05-28

19 answers

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]);
    }
}
 1849
Author: AgileJon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-02 16:46:05

Pod ECMAScript 5 możesz połączyć Object.keys() i 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]);

});
 598
Author: Axel Rauschmayer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-27 07:51:47

Problem z tym

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

Jest to, że będziesz również w pętli przez prototyp prymitywnego obiektu.

Tym unikniesz:

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]);
         }
      }
   }
}
 366
Author: Chango,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-21 05:11:35

W ES6 możesz zapętlić obiekt w taki sposób: (używając funkcji strzałek )

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

W ES7 możesz użyć Object.entries zamiast Object.keys i pętli przez obiekt taki jak ten:

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

Powyższy działałby również jako jednowierszowy :

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

Jsbin

Jeśli chcesz pętli przez zagnieżdżone obiekty, można użyć funkcji rekurencyjnej "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

Tak samo jak funkcja powyżej, ale z ES7 Object.entries zamiast 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.
  });
};

Jeśli lubisz Programowanie funkcyjne możesz użyć Object.keys/Object.entries aby wyliczyć obiekt, następnie przetworzyć wartości, a następnie użyć reduce() do konwersji z powrotem do nowego obiektu.

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.
      {});
 166
Author: Rotareti,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-13 09:18:35

Using Underscore.js ' s _.each:

_.each(validation_messages, function(value, key){
    _.each(value, function(value, key){
        console.log(value);
    });
});
 94
Author: Tim Santeford,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-17 11:14:58

Jeśli użyjesz rekurencji, możesz zwrócić właściwości obiektu o dowolnej głębokości -

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
}

*/
 53
Author: kennebec,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-18 00:01:48

Wiem, że jest waaay późno, ale zajęło mi 2 minuty, aby napisać tę zoptymalizowaną i ulepszoną wersję odpowiedzi Agilejona:

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
Author: Azder,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-21 05:41:34
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
Author: chaos,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-28 16:20:56

Ta odpowiedź jest zbiorem rozwiązań, które zostały przedstawione w tym post z jakimś wykonaniem informacje zwrotne . Myślę, że jest 2 przypadków użycia i OP nie wspomniał, czy musi uzyskać dostęp do kluczy, aby z nich korzystać podczas procesu pętli.

I. klucze muszą być dostępne,

✔ podejście of i Object.keys

let k;
for (k of Object.keys(obj)) {

    /*        k : key
     *   obj[k] : value
     */
}

✔ podejście in

let k;
for (k in obj) {

    /*        k : key
     *   obj[k] : value
     */
}

Użyj tego z ostrożne, ponieważ może drukować prototypowe właściwości obj

✔ podejście ES7

for (const [key, value] of Object.entries(obj)) {

}

jednak w czasie edycji nie polecałbym metody ES7, ponieważ JavaScript inicjalizuje wiele zmiennych wewnętrznie, aby zbudować tę procedurę(zobacz informacje zwrotne dla dowodu). O ile nie rozwijasz ogromnej aplikacji, która zasługuje na optymalizację, to jest ok, ale jeśli optymalizacja jest twoim priorytetem, powinieneś o tym pomyśleć.

II. po prostu musimy uzyskać dostęp do każdej wartości,

✔ podejście of i Object.values

let v;
for (v of Object.values(obj)) {

}

Więcej informacji zwrotnych na temat testów:

  • buforowanie Object.keys lub Object.values wydajność jest znikoma

Na przykład,

const keys = Object.keys(obj);
let i;
for (i of keys) {
  //
}
// same as
for (i of Object.keys(obj)) {
  //
}
  • W przypadku Object.values użycie natywnej pętli for z buforowanymi zmiennymi w Firefoksie wydaje się być nieco szybsze niż użycie pętli for...of. Jednak różnica nie jest aż tak ważna i Chrome działa for...of szybszy niż natywny for loop, więc polecam używać for...of przy radzeniu sobie z Object.values w każdym przypadku (testy 4 i 6).

  • W Firefoksie pętla for...in jest bardzo powolna, więc jeśli chcemy buforować klucz podczas iteracji, lepiej użyć Object.keys. Dodatkowo Chrome uruchamia obie struktury z jednakową prędkością(pierwszy i ostatni test).

Możesz sprawdzić testy tutaj : https://jsperf.com/es7-and-misc-loops

 24
Author: vdegenne,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-05 02:20:55
for(var key in validation_messages){
    for(var subkey in validation_messages[key]){
        //code here
        //subkey being value, key being 'yourname' / 'yourmsg'
    }
}
 8
Author: Dmitri Farkov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-28 16:53:15

P jest wartością

for (var key in p) {
  alert(key + ' => ' + p[key]);
}

Lub

Object.keys(p).forEach(key => { console.log(key, p[key]) })
 7
Author: Wesam,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-03 11:37:56

W ES7 możesz zrobić:

for (const [key, value] of Object.entries(obj)) {
  //
}
 6
Author: Kévin Berthommier,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-07 13:22:54

Oto ulepszona i rekurencyjna wersja rozwiązania AgileJon (demo):

function loopThrough(obj){
  for(var key in obj){
    // skip loop if the property is from prototype
    if(!obj.hasOwnProperty(key)) continue;

    if(typeof obj[key] !== 'object'){
      //your code
      console.log(key+" = "+obj[key]);
    } else {
      loopThrough(obj[key]);
    }
  }
}
loopThrough(validation_messages);

To rozwiązanie działa na różnego rodzaju głębokościach.

 5
Author: JepZ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-23 20:57:18

Inna opcja:

var testObj = {test: true, test1: false};
for(let x of Object.keys(testObj)){
    console.log(x);
}
 4
Author: dude,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-23 14:05:15

Myślę, że warto zwrócić uwagę, że jQuery porządkuje to ładnie $.each().

Zobacz: https://api.jquery.com/each/

Na przykład:

$('.foo').each(function() {
    console.log($(this));
});

$(this) będąc pojedynczym elementem wewnątrz obiektu. Zamień $('.foo') na zmienną, jeśli nie chcesz używać selektora jQuery.

 3
Author: Daniel Dewhurst,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-03 10:03:06

ECMAScript-2017, ukończony miesiąc temu, wprowadza obiekt.wartości(). Więc teraz możesz to zrobić:

let v;
for (v of Object.values(validation_messages))
   console.log(v.your_name);   // jimmy billy
 3
Author: Chong Lip Phang,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-24 01:45:41

Nie mogłem uzyskać powyższe posty, aby zrobić dokładnie to, co chciałem.

Po zabawie z innymi odpowiedziami tutaj, zrobiłem to. Jest hacky, ale działa!

Dla tego obiektu:

var myObj = {
    pageURL    : "BLAH",
    emailBox   : {model:"emailAddress", selector:"#emailAddress"},
    passwordBox: {model:"password"    , selector:"#password"}
};

... ten kod:

// Get every value in the object into a separate array item ...
function buildArray(p_MainObj, p_Name) {
    var variableList = [];
    var thisVar = "";
    var thisYes = false;
    for (var key in p_MainObj) {
       thisVar = p_Name + "." + key;
       thisYes = false;
       if (p_MainObj.hasOwnProperty(key)) {
          var obj = p_MainObj[key];
          for (var prop in obj) {
            var myregex = /^[0-9]*$/;
            if (myregex.exec(prop) != prop) {
                thisYes = true;
                variableList.push({item:thisVar + "." + prop,value:obj[prop]});
            }
          }
          if ( ! thisYes )
            variableList.push({item:thisVar,value:obj});
       }
    }
    return variableList;
}

// Get the object items into a simple array ...
var objectItems = buildArray(myObj, "myObj");

// Now use them / test them etc... as you need to!
for (var x=0; x < objectItems.length; ++x) {
    console.log(objectItems[x].item + " = " + objectItems[x].value);
}

... tworzy to w konsoli:

myObj.pageURL = BLAH
myObj.emailBox.model = emailAddress
myObj.emailBox.selector = #emailAddress
myObj.passwordBox.model = password
myObj.passwordBox.selector = #password
 2
Author: user1833875,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-09 14:28:04

Rozwiązanie, które działa dla mnie jest następujące

_private.convertParams=function(params){
    var params= [];
    Object.keys(values).forEach(function(key) {
        params.push({"id":key,"option":"Igual","value":params[key].id})
    });
    return params;
}
 0
Author: Jorge Santos Neill,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-22 03:42:45

W moim przypadku (na podstawie poprzedniego) jest możliwa dowolna ilość poziomów.

var myObj = {
    rrr: undefined,
    pageURL    : "BLAH",
    emailBox   : {model:"emailAddress", selector:"#emailAddress"},
    passwordBox: {model:"password"    , selector:"#password"},
    proba: {odin:{dva:"rr",trr:"tyuuu"}, od:{ff:5,ppa:{ooo:{lll:'lll'}},tyt:'12345'}}
};


function lookdeep(obj,p_Name,gg){
    var A=[], tem, wrem=[], dd=gg?wrem:A;
    for(var p in obj){
        var y1=gg?'':p_Name, y1=y1 + '.' + p;
        if(obj.hasOwnProperty(p)){
           var tem=obj[p];
           if(tem && typeof tem=='object'){
               a1=arguments.callee(tem,p_Name,true);
               if(a1 && typeof a1=='object'){for(i in a1){dd.push(y1 + a1[i])};}
            }
            else{
               dd.push(y1 + ':' + String(tem));
            }
        }
    };
    return dd
};


var s=lookdeep(myObj,'myObj',false);
for (var x=0; x < s.length; ++x) {
console.log(s[x]+'\n');}

Wynik:

["myObj.rrr:undefined",
"myObj.pageURL:BLAH",
"myObj.emailBox.model:emailAddress",
"myObj.emailBox.selector:#emailAddress",
"myObj.passwordBox.model:password",
"myObj.passwordBox.selector:#password",
"myObj.proba.odin.dva:rr",
"myObj.proba.odin.trr:tyuuu",
"myObj.proba.od.ff:5",
"myObj.proba.od.ppa.ooo.lll:lll",
"myObj.proba.od.tyt:12345"]
 -6
Author: user2515312,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-24 15:02:13