如何迭代JavaScript对象?

632

我在JavaScript中有一个对象:

{
    abc: '...',
    bca: '...',
    zzz: '...',
    xxx: '...',
    ccc: '...',
    // ...
}

我想使用一个for循环来获取它的属性。并且我想分部迭代它(不是一次性迭代所有对象属性)。

对于一个简单的数组,我可以用标准的for循环来做到这一点:

for (i = 0; i < 100; i++) { ... } // first part
for (i = 100; i < 300; i++) { ... } // second
for (i = 300; i < arr.length; i++) { ... } // last

但是如何用对象实现它呢?


32
请记住,对象属性不是按顺序存储的。当您遍历对象时,无法保证它们出现的顺序。 - James Allardice
@JamesAllardice的评论是来自2013年的。自2015年起,对象现在具有定义的迭代顺序。 - undefined
19个回答

1260

使用 for .. in 迭代 数组、字符串或对象 的键:

for (let key in yourobject) {
  console.log(key, yourobject[key]);
}

使用ES6,如果您需要同时获取键和值,请执行以下操作

for (let [key, value] of Object.entries(yourobject)) {
    console.log(key, value);
}
为避免记录继承属性,请使用hasOwnProperty进行检查:

使用hasOwnProperty函数,可以避免记录继承自原型链的属性。

for (let key in yourobject) {
   if (yourobject.hasOwnProperty(key)) {
      console.log(key, yourobject[key]);
   }
}
如果您使用简单的对象(例如使用 {} 创建的对象),则在迭代键时不需要检查 hasOwnProperty

这篇 MDN 文档 通俗易懂地解释了如何处理对象及其属性。

如果想要“分批”进行,最好的方法是将键提取到数组中。由于顺序不能保证,这是正确的方式。在现代浏览器中,可以使用

let keys = Object.keys(yourobject);

为了更好的兼容性,你最好这样做:

 let keys = [];
 for (let key in yourobject) {      
     if (yourobject.hasOwnProperty(key)) keys.push(key);
 }

然后您可以通过索引迭代您的属性:yourobject[keys[i]]

for (let i=300; i < keys.length && i < 600; i++) { 
   console.log(keys[i], yourobject[keys[i]]);
}

4
OP希望能够分块执行此操作,而不是在单个循环中处理所有的键。 - pawel
2
@Cerbrus,原帖作者已经知道如何对数组进行部分迭代了。使用给定代码中的“keys”应该就足够了。 - Yoshi
2
@Cerbrus 在评论之前请仔细阅读!“为了更兼容,最好这样做”有什么不清楚的吗? - Denys Séguret
2
@am05mhz 正如我所说,它对大多数对象都是无用的。但并非全部如此。请尝试这个链接:http://jsbin.com/hirivubuta/1/edit?js,console,output - Denys Séguret
6
我在 JavaScript 方面有 9 年的开发经验,但我经常对于 for..offor..in 感到自己不确定,最终来到这里。 - choz
显示剩余10条评论

98

这里是现代浏览器的另一种迭代解决方案:

Object.keys(obj)
  .filter((k, i) => i >= 100 && i < 300)
  .forEach(k => console.log(obj[k]));

或者不使用过滤函数:

Object.keys(obj).forEach((k, i) => {
    if (i >= 100 && i < 300) {
        console.log(obj[k]);
    }
});

然而,您必须考虑JavaScript对象中的属性未经排序,即没有顺序。


如果我打破循环,下一次它将从对象的开头开始,这不是正确的方法。 - nkuhta

49

使用Object.entries,你可以像这样操作。

 // array like object with random key ordering
 const anObj = { 100: 'a', 2: 'b', 7: 'c' };
 console.log(Object.entries(anObj)); // [ ['2', 'b'],['7', 'c'],['100', 'a'] ]

Object.entries()方法返回一个给定对象自身可枚举属性 [key, value] 的数组。

因此,您可以遍历Object并针对每个对象获取keyvalue,得到类似以下的结果。

const anObj = { 100: 'a', 2: 'b', 7: 'c' };
Object.entries(anObj).map(obj => {
   const key   = obj[0];
   const value = obj[1];

   // do whatever you want with those values.
});

或者像这样

// Or, using array extras
Object.entries(obj).forEach(([key, value]) => {
  console.log(`${key} ${value}`); // "a 5", "b 7", "c 9"
});

请参考 MDN 文档中关于 Object.entries() 的说明。


1
页面上的最佳答案 - Julius Goddard
即使你不是“map”的粉丝,entries()也是本世纪最好的东西。 - tekHedd

22

使用新的ES6/ES2015特性,您不再需要使用对象来迭代哈希表。您可以使用Map。Javascript Maps按插入顺序保留键,这意味着您可以在不必检查hasOwnProperty(这总是一种hack)的情况下对它们进行迭代。

遍历一个Map:

var myMap = new Map();
myMap.set(0, "zero");
myMap.set(1, "one");
for (var [key, value] of myMap) {
  console.log(key + " = " + value);
}
// Will show 2 logs; first with "0 = zero" and second with "1 = one"

for (var key of myMap.keys()) {
  console.log(key);
}
// Will show 2 logs; first with "0" and second with "1"

for (var value of myMap.values()) {
  console.log(value);
}
// Will show 2 logs; first with "zero" and second with "one"

for (var [key, value] of myMap.entries()) {
  console.log(key + " = " + value);
}
// Will show 2 logs; first with "0 = zero" and second with "1 = one"

或者使用 forEach:

myMap.forEach(function(value, key) {
  console.log(key + " = " + value);
}, myMap)
// Will show 2 logs; first with "0 = zero" and second with "1 = one"

2
forEach是首选。 - pungggi

19

如果你想在迭代时获取键和值,可以使用带有for...of循环和Object.entries方法。

const myObj = {a: 1, b: 2}

for (let [key, value] of Object.entries(myObj)) {
    console.log(`key=${key} value=${value}`)
}

// output: 
// key=a value=1
// key=b value=2

8
唯一可靠的方法是将对象数据保存到2个数组中,一个用于键,另一个用于数据:
var keys = [];
var data = [];
for (var key in obj) {
    if (obj.hasOwnProperty(key)) {
        keys.push(key);
        data.push(obj[key]); // Not necessary, but cleaner, in my opinion. See the example below.
    }
}

您可以像平常一样遍历这些数组:
for(var i = 0; i < 100; i++){
    console.log(keys[i], data[i]);
    //or
    console.log(keys[i], obj[keys[i]]); // harder to read, I think.
}
for(var i = 100; i < 300; i++){
    console.log(keys[i], data[i]);
}

我不使用 Object.keys(obj),因为这需要 IE 9+。


5

->如果我们使用遍历JavaScript对象并查找对象数组的键

Object.keys(Array).forEach(key => {

 console.log('key',key)

})

3

定义参数中的对象并避免使用选择器和下标

有许多语法选择,但这种方法在闭包的参数中先定义对象,从而消除了迭代器中需要使用选择器或下标的需要。 k 是键,v 是值,i 是索引。

const obj = {
    kiwi: true,
    mango: false,
    pineapple: 500
};

Object.entries(obj).forEach(([k, v], i) => {
    console.log(k, v, i);
});

// kiwi true 0
// mango false 1
// pineapple 500 2

3
如果您有一个简单的对象,您可以使用以下代码进行迭代:

let myObj = {
  abc: '...',
  bca: '...',
  zzz: '...',
  xxx: '...',
  ccc: '...',
  // ...
};

let objKeys = Object.keys(myObj);

//Now we can use objKeys to iterate over myObj

for (item of objKeys) {
  //this will print out the keys
  console.log('key:', item);
  
  //this will print out the values 
  console.log('value:', myObj[item]);
}

如果您有一个嵌套对象,可以使用以下代码进行迭代:

let b = {
  one: {
    a: 1,
    b: 2,
    c: 3
  },
  two: {
    a: 4,
    b: 5,
    c: 6
  },
  three: {
    a: 7,
    b: 8,
    c: 9
  }
};

let myKeys = Object.keys(b);

for (item of myKeys) {
  //print the key
  console.log('Key', item)
  
  //print the value (which will be another object)
  console.log('Value', b[item])
  
  //print the nested value
  console.log('Nested value', b[item]['a'])
}

如果您有一个对象数组,您可以使用以下代码遍历它:

let c = [
{
  a: 1,
  b: 2
},
{
  a: 3,
  b: 4
}
];

for(item of c){
//print the whole object individually 
console.log('object', item);

//print the value inside the object
console.log('value', item['a']);
}


2
const o = {
  name: "Max",
  location: "London"
};

for (const [key, value] of Object.entries(o)) {
  console.log(`${key}: ${value}`);
}

在线体验


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接