首先我们有这样一个对象:
var o = {};
var c = Symbol();
Object.defineProperties(o, {
a: {
value: 1,
},
b: {
enumerable: true,
configurable: true,
value: 5,
},
[c]: {
writable: true,
value: 10,
},
});
1、然后我们使用常见的遍历对象的方法for…in和获取对象值的方法Object.values()来试验一下是否可以获取到对象o的所有属性。
for(var prop in o){
console.log(prop);
}
// 打印结果只有"b"
var arr=Object.values(o);
console.log(arr);
// 打印结果是[5]
两种方法的打印结果说明它们都是只能获取可枚举属性,所以这两种方法都是不能用来获取对象属性的。
那么我们应该使用什么方法来获取对象的所有属性呢?
2、其实,Object还提供了这样两个方法getOwnPropertyNames()和getOwnPropertySymbols(),我们分别使用一下这两个方法。
var arr = Object.getOwnPropertyNames(o);
console.log(arr);
// 打印结果是 ["a", "b"]
var list = Object.getOwnPropertySymbols(o);
console.log(list);
// 打印结果是 [Symbol()]
根据上面的打印结果我们可以得知:getOwnPropertyNames方法获取对象上所有的字符串属性名,而getOwnPropertySymbols方法获取对象上所有Symbol属性名。
这样,我们将两个方法结合起来就可以获取到以Symbol类型为属性名的属性对应的属性值了:
var arr = Object.getOwnPropertyNames(o);
var list = Object.getOwnPropertySymbols(o);
console.log(o[list[0]]); //10
3、拓展:
如果是使用Object.defineProperty()方法设置的属性,它的描述对象怎么获取到呢?我们可以使用对象的getOwnPropertyDescriptor()方法来实现这个作用。
通过下面的操作,我们就可以将上面定义的对象o的所有属性完全地复制给另一个对象。
var o1 = {};
var names = Object.getOwnPropertyNames(o);
var list = Object.getOwnPropertySymbols(o);
for (var i = 0; i < names.length; i++) {
var desc = Object.getOwnPropertyDescriptor(o, names[i]);
Object.defineProperty(o1, names[i], desc);
}
for (var j = 0; j < list.length; j++) {
var desc = Object.getOwnPropertyDescriptor(o, list[j]);
Object.defineProperty(o1, list[j], desc);
}
console.log(o1, o);
console.log(o1 === o);
最后我们的打印结果如图:
根据打印结果,我们可以确定对象o完全复制给了对象o1,包括对象o的属性的描述对象,并且对象o和o1之间是没有引用关系的。