Pertanyaan Bagaimana mengulang melalui objek JavaScript polos dengan objek sebagai anggota?


Bagaimana saya bisa mengulang melalui semua anggota dalam objek JavaScript termasuk nilai-nilai yang merupakan objek.

Sebagai contoh, bagaimana saya bisa melewati ini (mengakses "your_name" dan "your_message" untuk masing-masing)?

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


asal


Jawaban:


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



Di bawah ECMAScript 5, Anda dapat menggabungkan Object.keys() dan 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



Masalah dengan ini

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

adalah Anda juga akan mengulang melalui prototipe objek primitif.

Dengan ini, Anda akan menghindarinya:

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



Di ES6 Anda dapat mengulang melalui objek seperti ini: (menggunakan fungsi panah)

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

Di ES7 Kamu dapat memakai Object.entries dari pada Object.keys dan mengulang melalui objek seperti ini:

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

Di atas juga akan berfungsi sebagai satu-liner:

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

jsbin

Jika Anda ingin mengulang melalui objek bersarang juga, Anda dapat menggunakan rekursif function (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

Sama seperti fungsi di atas, tetapi dengan ES7 Object.entries dari pada 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.
  });
};

Jika Anda tertarik pemrograman fungsional Kamu dapat memakai Object.keys/Object.entries untuk menghitung objek, lalu proses nilai dan kemudian gunakan reduce() untuk mengkonversi kembali ke objek baru.

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



Menggunakan Underscore.js's _.each:

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

93
2017-09-16 12:11



Jika Anda menggunakan rekursi, Anda dapat mengembalikan properti objek dari setiap kedalaman-

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



Saya tahu ini terlambat, tetapi butuh waktu 2 menit untuk menulis versi jawaban AgileJon yang dioptimalkan dan ditingkatkan ini:

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



Jawaban ini merupakan agregat dari solusi yang disediakan dalam hal ini   posting dengan beberapa kinerja   masukan. Saya pikir ada 2   use-cases dan OP tidak menyebutkan apakah dia perlu mengakses kunci untuk menggunakannya   selama proses loop.

I. kunci harus diakses,

 itu of dan Object.keys pendekatan

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

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

 itu in pendekatan

let k;
for (k in obj) {

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

Gunakan ini dengan hati-hati, karena bisa mencetak prototipe dari properti obj

 pendekatan ES7

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

}

Namun, pada saat pengeditan saya tidak akan merekomendasikan metode ES7, karena JavaScript menginisialisasi banyak variabel secara internal untuk membangun prosedur ini (lihat masukan untuk pembuktian). Kecuali Anda tidak mengembangkan aplikasi besar yang layak dioptimalkan, maka tidak apa-apa tetapi jika optimasi adalah prioritas Anda, Anda harus memikirkannya.

II. kita hanya perlu mengakses setiap nilai,

 itu of dan Object.values pendekatan

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

}

Lebih banyak masukan tentang tes:

  • Caching Object.keys atau Object.values kinerja dapat diabaikan

Contohnya,

const keys = Object.keys(obj);
let i;
for (i of keys) {
  //
}
// same as
for (i of Object.keys(obj)) {
  //
}
  • Untuk Object.values kasus, menggunakan penduduk asli for loop dengan variabel cache di Firefox tampaknya sedikit lebih cepat daripada menggunakan for...of lingkaran. Namun perbedaannya tidak begitu penting dan Chrome sedang berjalan for...of lebih cepat dari aslinya for loop, jadi saya akan merekomendasikan untuk digunakan for...of ketika berhadapan dengan Object.values dalam beberapa kasus (tes 4 dan 6).

  • Di Firefox, for...in loop benar-benar lambat, jadi ketika kita ingin menyimpan kunci selama iterasi lebih baik digunakan Object.keys. Plus Chrome menjalankan kedua struktur dengan kecepatan yang sama (tes pertama dan terakhir).

Anda dapat memeriksa tes di sini:    https://jsperf.com/es7-and-misc-loops


15
2017-09-24 03:34



for(var key in validation_messages){
    for(var subkey in validation_messages[key]){
        //code here
        //subkey being value, key being 'yourname' / 'yourmsg'
    }
}

8
2018-05-28 16:21



Ini dia versi perbaikan dan rekursif dari solusi 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);

Solusi ini berfungsi untuk semua jenis kedalaman yang berbeda.


5
2018-02-23 20:57