在JavaScript中,我们有4种方法可以获取对象中的属性,分别是for...in、Object.keys()、Object.getOwnPropertyNames()、Reflect.ownKeys(),下面分别说下他们之间的区别:
for...in
for...in循环会遍历对象自身的所有属性,以及它原型上的属性,并且,for...in只遍历对象中可枚举的属性(enumerate为true)。像 Array 和 Object 使用内置构造函数所创建的对象都会继承自 Object.prototype 和 String.prototype 的不可枚举属性。
可枚举属性:简单来说就是JS对象中的属性是否可以列举出来。
Object.keys(obj)
它可以得到自身可枚举的属性,但得不到原型链上的属性,同时Symbols 属性也得不到。
Object.getOwnPropertyNames(obj)
它可以得到自身所有的属性(包括可枚举属性以及不可枚举属性),但得不到原型链上的属性, 当然Symbols 属性也得不到.
Reflect.ownKeys(obj)
它可以得到对象的所有属性,基本等同于上述的Object.getOwnPropertyNames(obj)加上Object.getOwnPropertySymbols(obj)返回之和,这里的getOwnPropertySymbols方法单独只返回对象中包含symbols属性。
如果不够清晰?下面我们可以使用代码来解释上述内容的描述:
const animal = {
A: 1,
B: 2,
C: 3,
}
const cat = {
D: 4,
E: 5,
[Symbol()]: 6,
}
cat.__proto__ = animal
Object.defineProperty(cat, "E", { enumerable: false }); //定义E属性为不可枚举
for (let attrs in cat) {
console.log("for...in:", attrs) // A,B,C,D
}
console.log("Object.keys:", Object.keys(cat)) // [ 'D' ]
console.log("Object.getOwnPropertyNames:", Object.getOwnPropertyNames(cat)) // [ 'D', 'E' ]
console.log("Reflect.ownKeys:", Reflect.ownKeys(cat)) // [ 'D', 'E', Symbol() ]