2020.04.28(Object.getOwnPropertyDescriptors()、__proto__ 属性,Object.setPrototypeOf(), Object.getPrototypeOf())
Object.getOwnPropertyDescriptors()
ES5 的 Object.getOwnPropertyDescriptor() 方法会返回某个对象属性的描述对象
(descriptor)。ES2017 引入了 Object.getOwnPropertyDescriptors() 方法,返回指定对象
所有自身属性(非继承属性)的描述对象。
1. const obj = { 2. foo: 123, 3. get bar() { return 'abc' } 4. }; 5. 6. Object.getOwnPropertyDescriptors(obj) 7. // { foo: 8. // { value: 123, 9. // writable: true, 10. // enumerable: true, 11. // configurable: true }, 12. // bar: 13. // { get: [Function: get bar], 14. // set: undefined, 15. // enumerable: true, 16. // configurable: true } }
上面代码中, Object.getOwnPropertyDescriptors() 方法返回一个对象,所有原对象的属性名都
是该对象的属性名,对应的属性值就是该属性的描述对象。
该方法的引入目的,主要是为了解决 Object.assign() 无法正确拷贝 get 属性和 set 属性的问
题。
1. const source = { 2. set foo(value) { 3. console.log(value); 4. } 5. }; 6. 7. const target1 = {}; 8. Object.assign(target1, source); 9. 10. Object.getOwnPropertyDescriptor(target1, 'foo') 11. // { value: undefined, 12. // writable: true, 13. // enumerable: true, 14. // configurable: true }
上面代码中, source 对象的 foo 属性的值是一个赋值函数, Object.assign 方法将这个属性
拷贝给 target1 对象,结果该属性的值变成了 undefined 。这是因为 Object.assign 方法总
是拷贝一个属性的值,而不会拷贝它背后的赋值方法或取值方法。
这时, Object.getOwnPropertyDescriptors() 方法配合 Object.defineProperties() 方法,
就可以实现正确拷贝。
const source = { 2. set foo(value) { 3. console.log(value); 4. } 5. }; 6. 7. const target2 = {}; 8. Object.defineProperties(target2, Object.getOwnPropertyDescriptors(source)); 9. Object.getOwnPropertyDescriptor(target2, 'foo') 10. // { get: undefined, 11. // set: [Function: set foo], 12. // enumerable: true, 13. // configurable: true }
上面代码中,两个对象合并的逻辑可以写成一个函数。
__proto__ 属性,Object.setPrototypeOf(),
Object.getPrototypeOf()
JavaScript 语言的对象继承是通过原型链实现的。ES6 提供了更多原型对象的操作方法。
__proto__ 属性
__proto__ 属性(前后各两个下划线),用来读取或设置当前对象的原型对象(prototype)。目
前,所有浏览器(包括 IE11)都部署了这个属性。
1. // es5 的写法 2. const obj = { 3. method: function() { ... } 4. }; 5. obj.__proto__ = someOtherObj; 6. 7. // es6 的写法 8. var obj = Object.create(someOtherObj); 9. obj.method = function() { ... };
如果一个对象本身部署了 __proto__ 属性,该属性的值就是对象的原型。
1. Object.getPrototypeOf({ __proto__: null })
2. // null
Object.setPrototypeOf()
Object.setPrototypeOf 方法的作用与 __proto__ 相同,用来设置一个对象的原型对象
(prototype),返回参数对象本身。它是 ES6 正式推荐的设置原型对象的方法。
1. // 格式 2. Object.setPrototypeOf(object, prototype) 3. 4. // 用法 5. const o = Object.setPrototypeOf({}, null);
下面是一个例子。
1. let proto = {}; 2. let obj = { x: 10 }; 3. Object.setPrototypeOf(obj, proto); 4. 5. proto.y = 20; 6. proto.z = 40; 7. 8. obj.x // 10 9. obj.y // 20 10. obj.z // 40
上面代码将 proto 对象设为 obj 对象的原型,所以从 obj 对象可以读取 proto 对象的属性。
如果第一个参数不是对象,会自动转为对象。但是由于返回的还是第一个参数,所以这个操作不会产生
任何效果。
由于 undefined 和 null 无法转为对象,所以如果第一个参数是 undefined 或 null ,就会
报错。
1. Object.setPrototypeOf(undefined, {}) 2. // TypeError: Object.setPrototypeOf called on null or undefined 3. 4. Object.setPrototypeOf(null, {}) 5. // TypeError: Object.setPrototypeOf called on null or undefined
Object.getPrototypeOf()
该方法与 Object.setPrototypeOf 方法配套,用于读取一个对象的原型对象。
1. Object.getPrototypeOf(obj);
2021-04-28 10:50:20

浙公网安备 33010602011771号