如何迭代一个JavaScript对象?

我在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

但是如何对对象进行处理呢?

695749 次浏览

对于迭代数组、字符串或对象的键,使用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:

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

下面是另一个针对现代浏览器的迭代解决方案:

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对象中的属性是没有排序的,也就是说没有顺序。

唯一可靠的方法是将对象数据保存到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+。

如果你想一次迭代整个对象,你可以使用for in循环:

for (var i in obj) {
...
}

但如果你想把物体分成几部分实际上你做不到。不能保证对象中的属性按任何指定的顺序排列。因此,我可以想到两种解决方案。

首先是“删除”已经读取的属性:

var i = 0;
for (var key in obj) {
console.log(obj[key]);
delete obj[key];
if ( ++i > 300) break;
}

我能想到的另一个解决方案是使用数组的数组而不是对象:

var obj = [['key1', 'value1'], ['key2', 'value2']];

然后,标准的for循环将工作。

var Dictionary = {
If: {
you: {
can: '',
make: ''
},
sense: ''
},
of: {
the: {
sentence: {
it: '',
worked: ''
}
}
}
};


function Iterate(obj) {
for (prop in obj) {
if (obj.hasOwnProperty(prop) && isNaN(prop)) {
console.log(prop + ': ' + obj[prop]);
Iterate(obj[prop]);
}
}
}
Iterate(Dictionary);

有了新的ES6/ES2015特性,你不再需要使用对象来遍历散列。您可以使用地图。Javascript地图保持键的插入顺序,这意味着你可以迭代它们,而不必检查hasOwnProperty,这一直是一个真正的黑客。

迭代一个地图:

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"

->如果我们遍历一个JavaScript对象使用并找到数组的键 对象< / i > < / p >

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


console.log('key',key)


})

使用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]的数组。

你可以遍历对象,每个对象都有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文档

我最终想出了一个方便的实用工具函数,具有统一的接口来迭代对象,字符串,数组,TypedArrays, Maps, Sets,(任何Iterables)。

const iterate = require('@a-z/iterate-it');
const obj = { a: 1, b: 2, c: 3 };


iterate(obj, (value, key) => console.log(key, value));
// a 1
// b 2
// c 3

https://github.com/alrik/iterate-javascript

你可以尝试使用lodash-一个现代的JavaScript实用程序库,提供模块化、性能和扩展;临时演员 js来快速迭代对象:-

var  users  =   {
'fred':     { 
'user':   'fred',
    'age':  40 
},
'pebbles':  { 
'user':   'pebbles',
 'age':  1 
}
}; 
_.mapValues(users,  function(o)  { 
return  o.age; 
});
// => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
// The `_.property` iteratee shorthand.
console.log(_.mapValues(users,  'age')); // returns age property & value
console.log(_.mapValues(users,  'user')); // returns user property & value
console.log(_.mapValues(users)); // returns all objects
// => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash-compat/3.10.2/lodash.js"></script>

实际上,PITA不是标准Javascript的一部分。

/**
* Iterates the keys and values of an object.  Object.keys is used to extract the keys.
* @param object The object to iterate
* @param fn (value,key)=>{}
*/
function objectForEach(object, fn) {
Object.keys(object).forEach(key => {
fn(object[key],key, object)
})
}

注意:我将回调参数切换为(value,key),并添加了第三个对象以使API与其他API保持一致。

像这样使用它

const o = {a:1, b:true};
objectForEach(o, (value, key, obj)=>{
// do something
});

对于对象迭代,我们通常使用for..in循环。该结构将循环遍历所有可列举的属性,包括通过原型继承继承的属性。例如:

let obj = {
prop1: '1',
prop2: '2'
}


for(let el in obj) {
console.log(el);
console.log(obj[el]);
}

但是,for..in将遍历所有可枚举元素,这将不能将迭代分割成块。为了实现这一点,我们可以使用内置的Object.keys()函数来检索数组中对象的所有键。然后,我们可以将迭代分解为多个for循环,并使用keys数组访问属性。例如:

let obj = {
prop1: '1',
prop2: '2',
prop3: '3',
prop4: '4',
};


const keys = Object.keys(obj);
console.log(keys);




for (let i = 0; i < 2; i++) {
console.log(obj[keys[i]]);
}




for (let i = 2; i < 4; i++) {
console.log(obj[keys[i]]);
}

如果你想在迭代时使用键和值,你可以使用的……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

是的。可以使用for loop循环遍历对象。这里有一个例子

var myObj = {
abc: 'ABC',
bca: 'BCA',
zzz: 'ZZZ',
xxx: 'XXX',
ccc: 'CCC',
}


var k = Object.keys (myObj);
for (var i = 0; i < k.length; i++) {
console.log (k[i] + ": " + myObj[k[i]]);
}

注意:上面提到的例子只能在IE9+中工作。看到Objec。键浏览器支持在这里

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


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

试上网

如果你有一个简单的对象,你可以使用下面的代码迭代它:

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

这是一个手工制作的解决方案:

function iterationForObject() {
let base = 0,
Keys= Object.keys(this);
return {
next: () => {
return {
value: {
"key": Keys[base],
"value": this[Keys[base]]
},
done: !(base++ < Keys.length)
};
}
};
}
Object.prototype[Symbol.iterator] = iterationForObject;

然后你可以循环任何对象:

for ( let keyAndValuePair of (Object Here) ) {
console.log(`${keyAndValuePair.key} => ${keyAndValuePair.value}`);
}
<script type="text/javascript">
// method 1
var images = {};
images['name'] = {};
images['family'] = {};
images[1] = {};
images['name'][5] = "Mehdi";
images['family'][8] = "Mohammadpour";
images['family']['ok'] = 123456;
images[1][22] = 2602;
images[1][22] = 2602;
images[1][22] = 2602;
images[1][22] = 2602;
images[1][23] = 2602;


for (const [key1, value1] of Object.entries(images)){
for (const [key2, value2] of Object.entries(value1)){
console.log(`${key1} => ${key2}: ${value2}`);
}
}




console.log("=============================");


// method 2
var arr = [];
for(var x = 0; x < 5; x++){
arr[x] = [];
for(var y = 0; y < 5; y++){
arr[x][y] = x*y;
}
}


for(var i = 0; i < arr.length; i++) {
var cube = arr[i];
for(var j = 0; j < cube.length; j++) {
console.log("cube[" + i + "][" + j + "] = " + cube[j]);
}
}


</script>

在参数中定义object,避免选择器下标

有许多语法选择,但这个在闭包的参数中定义了前面的对象,从而消除了迭代器中选择器或下标的需要。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