# 对象遍历方法对比
Table of Contents
核心概念
在JavaScript中,遍历对象的方式有很多种,但不同的方法在性能开销,速度,可读性,可维护性等方面有较大的差异
可以围绕三方面来进行对比
- 可枚举性
- 原型链
- Symbols属性
示例
const sym = Symbol('sym') // 定义一个Symbol属性const proto = { name: 'proto',}
const obj = Object.create(proto) // 创建一个对象,并继承proto对象,proto成为新对象的原型对象// obj => proto => Object.prototype => null
obj.ownProperty = 'ownProperty' // 定义一个普通属性obj[sym] = 'sym' // 定义一个Symbol属性
Object.defineProperty(obj, 'nonEnumProp', { value: 'non-enumerable value', enumerable: false,});
console.log(obj) // { ownProperty: 'ownProperty', [Symbol(sym)]: 'sym', nonEnumProp: 'non-enumerable value' }
然后列举一些常用遍历对象的方法,并进行对比
可枚举性
for...in
:遍历对象的枚举属性,包括原型链上的属性,无法遍历Symbol属性Object.keys
:遍历对象的枚举属性,不包括原型链上的属性Object.values
:遍历对象的枚举属性,不包括原型链上的属性Object.entries
:遍历对象的枚举属性,不包括原型链上的属性
实际演示
1.for…in 遍历示例
2.Object.keys 遍历示例
3.Reflect.ownKeys 遍历示例
注意事项
for...in
陷阱,默认情况下,for...in
会遍历原型链,这是常见问题,为了避免这种意外行为,我们可以在循环体中使用hasOwnProperty
方法来判断属性是否是对象自身的属性
2.性能方面:
Object.keys
通常会比for...in
+hasOwnProperty
更快,因为Object.keys
不涉及原型链查找Reflect.ownKeys
因为会遍历自身属性,原型链,和Symbol属性,所以性能较差,但全面性更好