如何循环使用对象作为成员的普通 JavaScript 对象

IT技术 javascript loops
2021-02-05 02:44:27

如何遍历 JavaScript 对象中的所有成员,包括作为对象的值?

例如,我如何遍历这个(分别访问“your_name”和“your_message”)?

var validation_messages = {
    "key_1": {
        "your_name": "jimmy",
        "your_msg": "hello world"
    },
    "key_2": {
        "your_name": "billy",
        "your_msg": "foo equals bar"
    }
}
6个回答
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]);
    }
}
Internet Explorer 不同意(叹气),当您执行 obj[prop] 时说“对象不支持此属性或方法”。我还没有找到解决方案。
2021-03-26 02:44:27
对于现代浏览器(IE9+)来说,hasOwnProperty 几乎总是多余的。
2021-03-28 02:44:27
@MildFuzz 实际上,如果您认为 JS 对象不需要数字键,那是有道理的。你不能只是遍历一个对象。JSfor in与传统的foreach.
2021-04-02 02:44:27
for...in 是一个很好的解决方案,但是如果你在 for() 循环中使用 promise 时要小心,因为如果你在循环中创建了一个 var,你就不能在 promise 的 then 函数中使用它。循环中的 var 只存在一次,因此它在每个 then 函数中都相同,甚至是最后一个值。如果您有这个问题,请尝试“Object.keys(obj).forEach”或我在下面的回答。
2021-04-09 02:44:27

在 ECMAScript 5 下,您可以组合Object.keys()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]);

});

+1 为代码简洁,但显然,执行效率不如 for 令人惊讶。JSPerf - for in vs Object.keys
2021-03-20 02:44:27
@techiev2:并不是Object.keys()让它变慢,而是forEach()重复访问.length! 如果您改用经典的for-loop,它的速度几乎是 Firefox 33 中的for..in+ 的两倍hasOwnProperty()
2021-04-01 02:44:27
使用这种方法时要注意这个错误:“TypeError: Object.keys called on non-object”。for ... in ... hasOwnProperty据我所知(对象、数组、空值、未定义、真、假、数字基元、对象),可以在任何东西上调用模式。
2021-04-06 02:44:27
@techiev2 一点也不奇怪,Axel Rauschmayer 的方法是使用keys函数和forEach函数,它需要解析匿名函数,然后在 forEach 循环的每个元素上调用匿名函数。如果您了解编程,您就会明白所有这些解析和函数调用比原生解决方案(如 for 结构循环)花费的时间要多得多。
2021-04-06 02:44:27
@techiev2 这些测试从未有效。查看我更新的当前性能状态:jsperf.com/objdir/20
2021-04-08 02:44:27

ES6/2015 中,您可以像这样循环遍历对象(使用箭头函数):

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

JS斌

ES7/2016 中,您可以使用Object.entries代替Object.keys并循环遍历这样的对象:

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

以上也可以作为单行

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

jsbin

如果您还想遍历嵌套对象,则可以使用递归函数 (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.
  });
};

JS斌

与上面的函数相同,但使用ES7 Object.entries()而不是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.
  });
};

在这里,我们循环遍历嵌套对象的更改值,并Object.entries()结合使用Object.fromEntries()( ES10/2019 )一次性返回一个新对象

const loopNestedObj = obj =>
  Object.fromEntries(
    Object.entries(obj).map(([key, val]) => {
      if (val && typeof val === "object") [key, loopNestedObj(val)]; // recurse
      else [key, updateMyVal(val)]; // or do something with key and val.
    })
  );

另一种循环对象的方法是使用 for ... infor ... of请参阅vdegenne 写得很好的答案

我认为添加 Object.entries 和 Object.keys 不会迭代原型这一事实会很有用,这是原型与 for in 构造之间的巨大差异。
2021-04-01 02:44:27
对于使用 Object.entries 的 ES7 示例,您需要将箭头函数参数 [key,val] 包裹在括号中,例如:`Object.entries(myObj).forEach(([key, val]) => { /* statements* / }
2021-04-04 02:44:27

这个问题

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

是您还将遍历原始对象的原型。

有了这个,您将避免它:

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]);
         }
      }
   }
}
请注意,仅当您的对象具有原型方法时才需要这样做。例如,如果您循环的对象只是一个 JSON 对象,则不需要此检查。
2021-03-12 02:44:27
@rednaw 为了安全起见,我使用该检查是因为可以修改 Object.prototype。没有理智的脚本会这样做,但您无法控制哪些脚本可能会被疯狂的浏览器扩展程序在您的页面中运行。浏览器扩展在您的页面中运行(在大多数浏览器上)并且它们可能会导致奇怪的问题(例如将 window.setTimeout 设置为 null!)。
2021-03-13 02:44:27
简而言之:检查hasOwnProperty您的for-in循环。
2021-03-27 02:44:27

使用Underscore.js 的_.each

_.each(validation_messages, function(value, key){
    _.each(value, function(value, key){
        console.log(value);
    });
});
谢谢蒂姆,使用下划线绝对好,有一个快速和干净的选择。
2021-03-26 02:44:27