Object.keys, for in, Object.getOwnPropertyNames, Reflect.ownKeys 区别

1,367 阅读1分钟

原因

主要是回顾下基础知识,像这种获取对象属性集合的方法很多,之前记忆有点混淆了,写个实验代码,然后记录下。

测试代码:

let obj = Object.create({
  e: 5,
})

obj.a = 1

obj.b = 2

obj[Symbol('c')] = 3

Reflect.defineProperty(obj, 'd', {
  enumerable: false,
  value: 4,
})

// for in
for (let key in obj) {
  console.log(key) // a, b, e
}

// Object.keys
console.log(Object.keys(obj)) // [ 'a', 'b' ]

// getOwnPropertyNames
console.log(Object.getOwnPropertyNames(obj)) // [ 'a', 'b', 'd' ]

// ownKeys
console.log(Reflect.ownKeys(obj)) // [ 'a', 'b', 'd', Symbol(c) ]

区别

  • for in,遍历所有可枚举属性,原型属性。不包括不可枚举属性,Symbol
  • Object.keys(),获取自身可枚举属性。不包括不可枚举属性,原型属性,Symbol
  • Object.getOwnPropertyNames,获取自身所有属性名称,包括不可枚举属性。不包括Symbol,不包括原型
  • Reflect.ownKeys,获取自身所有属性名称,包括不可枚举属性,Symbol。不包括原型(其实就是Object.getOwnPropertyNames与Object.getOwnPropertySymbols之和)

对照表

方法/属性 可枚举 不可枚举 Symbol 原型
for in
Object.keys()
Object.getOwnPropertyNames
Reflect.ownKeys

结论

一般获取可枚举属性用Object.keys()就好了(如果想获取属性和值用Object.assign() )。如果想获取到原型上的枚举属性再用for in。

如果想获取自身的所有属性包括不可枚举的属性,推荐用Reflect.ownKeys。Reflect未来会替代掉Object的一些方法。