Object.getOwnPropertyDescriptors(obj)
的功能返回一个包含 obj 自身所有属性的属性描述符数组。
const obj = {
[Symbol('foo')]: 123,
get bar() { return 'abc' },
};
console.log(Object.getOwnPropertyDescriptors(obj));
输出:
从 ES6 开始,才有了一个用来复制属性的工具方法:Object.assign()
。但是,这个方法只能简单的使用 get 和 set 操作去复制那些本身就是关键字的属性。这也意味着它并不能正确地复制那些非默认属性。
const source = {
set foo(value) {
console.log(value);
}
};
console.log(Object.getOwnPropertyDescriptor(source, 'foo'));
使用Object.assign()
复制 foo 到 target 对象:
const target1 = {};
Object.assign(target1, source);
console.log(Object.getOwnPropertyDescriptor(target1, 'foo'));
然后我们把Object.getOwnPropertyDescriptors()
和Object.defineProperties()
组合起来却能得到我们想要的结果。
const target2 = {};
Object.defineProperties(target2, Object.getOwnPropertyDescriptors(source));
console.log(Object.getOwnPropertyDescriptor(target2, 'foo'));
对象的浅复制也可以使用Object.getOwnPropertyDescriptors()
。但是,这次我们用Object.create()
来尝试一下,这个方法有两个参数:
- 第一个参数指定用来返回的对象原型
- 第二个参数是一个类似于
Object.getOwnPropertyDescriptors()
方法返回的描述符属性集合
const clone = Object.create(Object.getPrototypeOf(obj), Object.getOwnPropertyDescriptors(obj));
使用对象字面量的最好方式就是创建一个对象,比如下面的示例中把内置属性__proto__
指向了另一个任意的对象prot
。
var prot = {
value: 1
}
const obj = {
__proto__: prot,
foo: 123,
};
console.log(obj.value)
//正确的输出了我们所期望的值
1
可惜的是,这种用法只是在浏览器环境中才支持。更通用的做法是使用Object.create()
和赋值操作。
var prot = {
value: 1
}
const obj = Object.create(prot);
obj.foo = 123;
console.log(obj.value)
//依然可以输出正确的值
1
还有一种实现方式就是使用Object.getOwnPropertyDescriptors()
var prot = {
value: 1
}
const obj = Object.create(
prot,
Object.getOwnPropertyDescriptors({
foo: 123,
})
);
console.log(obj.value)
//输出了正确的结果
1