javascript遍历对象的几种方法

总结下在JavaScript中遍历对象的几种方法。

for in

for in循环是最基础的遍历对象的方式,除了能拿到到对象自身的属性之外,它还能拿到对象原型链上的属性。

// 创建一个对象并指定其原型,yanggb为原型上的属性
const obj = Object.create({
 yanggb: 'yanggb'
})
 
// yanggb1为对象自身的属性
obj.yanggb1 = 'yanggb1'
 
for (let key in obj) {
 console.log(obj[key]) // yanggb1, yanggb
}

可以看到对象原型上的属性也被循环出来了,首先是遍历了自身的属性,然后逐层往上遍历原型链上原型的属性。

如果想要过滤掉原型链上的属性,也可以使用对象的hasOwnProperty()方法判断其是否是自身属性,以此来达到只针对自身的属性做相应操作的目的。

for (let key in obj) {
 if (obj.hasOwnProperty(key)) {
  console.log(obj[key]) // yanggb1
 }
}

这时候原型上的yanggb属性就被过滤掉了。

Object.keys

Object.keys()是ES5新增的一个对象方法,该方法返回对象自身属性名组成的数组,它会自动过滤掉原型链上的属性,然后可以通过数组的forEach()方法来遍历。

Object.keys(obj).forEach((key) => {
 console.log(obj[key]) // yanggb1
})

此外还有Object.values()方法和Object.entries()方法,这两方法的作用范围和Object.keys()方法类似,分别是取得对象的属性值数组和属性键值数组数组。

for in循环和Object.keys()方法一样,都不会返回对象的不可枚举属性,如果需要遍历不可枚举的属性,就要使用Object.getOwnPropertyNames()方法了。

Object.getOwnPropertyNames

Object.getOwnPropertyNames()同样也是ES5新增的一个对象方法,该方法会返回对象自身属性名组成的数组,包括不可枚举的属性,因此也可以通过数组的forEach()方法来遍历。

// 创建一个对象并指定其原型,yanggb为原型上的属性
// yanggb1为对象自身的属性并且不可枚举
const obj = Object.create({
 yanggb: 'yanggb'
}, {
 yanggb1: {
  value: 'yanggb1',
  enumerable: false
 }
})
 
obj.yanggb2 = 'yanggb2'
 
// 不包括不可枚举的yanggb1属性
Object.keys(obj).forEach((key) => {
 console.log(obj[key]) // yanggb1
})
 
// 包括不可枚举的yanggb1属性
Object.getOwnPropertyNames(obj).forEach((key) => {
 console.log(obj[key]) // yanggb1,yanggb2
})

而在ES2015新增了Symbol数据类型,该类型可以作为对象的键。针对该类型,ES2015同样新增了一个Object.getOwnPropertySymbols()方法。

Object.getOwnPropertySymbols

Object.getOwnPropertySymbols()方法返回对象自身的Symbol属性组成的数组,不包括字符串属性等其他属性。

Object.getOwnPropertySymbols(obj).forEach((key) => {
 console.log(obj[key])
})

此时什么都没有输出,因为该对象还没有Symbol属性。

// 给对象添加一个不可枚举的Symbol属性
Object.defineProperties(obj, {
 [Symbol('yanggb')]: {
  value: 'Symbol yanggb',
  enumerable: false
 }
})
 
// 给对象添加一个可枚举的Symbol属性
obj[Symbol('yanggb1')] = 'Symbol yanggb1'
 
Object.getOwnPropertySymbols(obj).forEach((key) => {
 console.log(obj[key]) // Symbol yanggb, Symbol yanggb1
})

这时候就会输出所有的Symbol属性,包括可枚举不可枚举Symbol属性。

Reflect.ownKeys

Reflect.ownKeys()方法是ES2015新增的一个静态方法,该方法返回对象自身所有属性名组成的数组,包括不可枚举的属性和Symbol属性。

Reflect.ownKeys(obj).forEach((key) => {
 console.log(obj[key]) // yanggb, yanggb1, Symbol yanggb, Symbol yanggb1
})

既然方法有那么多,自然需要对比一下才能知道不同的场景该怎么选用。

几种方法的对比

通过一个表格直观得对比:

方式 基本属性 原型链 不可枚举 Symbol
for in
Object.keys()
Object.getOwnPropertyNames()
Object.getOwnPropertySymbols()
Reflect.ownKeys()

这其中只有for in循环会得到对象原型链上的属性,其它方法都只适用于对象自身的属性。

ES语言后续添加的新特性不会对以前的代码产生副作用,比如在ES2015之前就存在的for in循环,Object.keys()和Object.getOwnPropertyNames()是肯定不会返回Symbol属性的。

"成长的经历,大概能让人变得越来越安静。"

原文地址:https://www.cnblogs.com/yanggb/p/13568354.html