Skip to content

Latest commit

 

History

History
126 lines (89 loc) · 3.07 KB

Object.getOwnPropertyDescriptors().md

File metadata and controls

126 lines (89 loc) · 3.07 KB

Object.getOwnPropertyDescriptors(obj)的功能返回一个包含 obj 自身所有属性的属性描述符数组。

const obj = {
    [Symbol('foo')]: 123,
    get bar() { return 'abc' },
};
console.log(Object.getOwnPropertyDescriptors(obj));

输出:

image

应用场景

复制若干属性给一个对象

从 ES6 开始,才有了一个用来复制属性的工具方法:Object.assign()。但是,这个方法只能简单的使用 get 和 set 操作去复制那些本身就是关键字的属性。这也意味着它并不能正确地复制那些非默认属性。

const source = {
    set foo(value) {
        console.log(value);
    }
};
console.log(Object.getOwnPropertyDescriptor(source, 'foo'));

image

使用Object.assign()复制 foo 到 target 对象:

const target1 = {};
Object.assign(target1, source);
console.log(Object.getOwnPropertyDescriptor(target1, 'foo'));

image

然后我们把Object.getOwnPropertyDescriptors()Object.defineProperties()组合起来却能得到我们想要的结果。

const target2 = {};
Object.defineProperties(target2, Object.getOwnPropertyDescriptors(source));
console.log(Object.getOwnPropertyDescriptor(target2, 'foo'));

image

对象复制

对象的浅复制也可以使用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