Object对象遍历的几种方法

Object对象遍历的几种方法

本文以下面对象为例:

1
2
3
4
const person = {
name: 'andy',
age: 12
};

1. Object.keys

forEach原本只是用来遍历数组对象,所以需要先获取对象的所有key,再行遍历。需要注意的是

Object.keys获取参数对象自身的(不含继承的)所有可枚举属性(不含Symbol属性)的key值:

1
2
3
4
5
6
Object.keys(person).forEach((key) => {
console.log(key);
})

// name
// age

2. Object.values

Object.values返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历属性的键值:

1
2
3
4
5
6
Object.values(person).forEach(value => {
console.log(value);
})

// andy
// 12

3. Object.entries

Object.entries返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历属性的键值对数组。

1
2
3
4
5
6
Object.entries(person).forEach((arr) => {
console.log(arr);
})

// ['name', 'andy']
// ['age', 12]

4. getOwnPropertyNames

getOwnPropertyNames返回包含对象自身的所有属性(不含Symbol属性,但是包含不可枚举属性)

1
2
3
4
5
6
Object.getOwnPropertyNames(person).forEach(key => {
console.log(key);
})

// name
// age

5. Reflect.ownKeys

Reflect.ownKeys返回对象自身的所有属性,包括symbol属性,不可枚举属性等:

1
2
3
4
5
6
Reflect.ownKeys(person).forEach(key => {
console.log(key);
})

// name
// age

6. for...in

for...in获取对象自身的和继承的可枚举属性(不含Symbol属性):

1
2
3
4
5
for (let key in person) {
console.log(key);
}
// name
// age

如果要遍历对象自身的属性,可以使用hasOwnProperty方法进行二次判断:

1
2
3
4
5
6
7
8
for(let key in person) {
if(person.hasOwnProperty(key)) {
console.log(key)
}
}

// name
// age

7. for...of

for...of支持数组和类数组的对象遍历,但是不能支持所有的对象遍历。这是因为ES6引入了Iterator接口,包含此接口的数据结构皆能够被for...of遍历,所以我们可以稍加改造,让for...of可以遍历所有的对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
person[Symbol.iterator] = function() {
let index = 0;
let self = this;
let keys = Object.keys(self);

return {
next() {
if (index < keys.length) {
return {
value: self[keys[index++]],
done: false
}
} else {
return {
value: undefined,
done: true
}
}
}
}
}

仔细观察上面代码,你会发现其实[Symbol.iterator]函数是一个Generator函数,那么就可以简化一下:

1
2
3
4
5
6
7
person[Symbol.iterator] = function* () {
let keys = Object.keys(this);

for (let i = 0; i < keys.length; i++) {
yield keys[i];
}
}

对于上面只返回了key的代码还可以进一步优化:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
person[Symbol.iterator] = function* () {
let keys = Object.keys(this);

for (let i = 0; i < keys.length; i++) {
yield [keys[i], this[keys[i]]]
}
}

// 遍历结果
for(let [key, value] of person) {
console.log(key, value);
}

// name, andy
// age, 12