原因
主要是回顾下基础知识,像这种获取对象属性集合的方法很多,之前记忆有点混淆了,写个实验代码,然后记录下。
测试代码:
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的一些方法。