Object.getOwnPropertyDescriptors

简介

ES5 的 Object.getOwnPropertyDescriptor() 方法会返回某个对象属性的描述对象(descriptor)。ES2017 引入了 Object.getOwnPropertyDescriptors() 方法,返回指定对象所有自身属性(非继承属性)的描述对象。

语法

基本用法如下。

const obj = {
  foo: 123,
  get bar() {
    return 'abc'
  },
}

Object.getOwnPropertyDescriptors(obj)
// { foo:
//    { value: 123,
//      writable: true,
//      enumerable: true,
//      configurable: true },
//   bar:
//    { get: [Function: get bar],
//      set: undefined,
//      enumerable: true,
//      configurable: true } }

该方法的实现非常容易。

function getOwnPropertyDescriptors(obj) {
  const result = {}
  for (let key of Reflect.ownKeys(obj)) {
    result[key] = Object.getOwnPropertyDescriptor(obj, key)
  }
  return result
}

该方法引入的目的,主要是为了解决 Object.assign() 无法正确拷贝 get 属性和 set 属性的问题。Object.assign 方法总是拷贝一个属性的值,而不会拷贝它背后的赋值方法或取值方法。

这时,Object.getOwnPropertyDescriptors() 方法配合 Object.defineProperties() 方法,就可以实现正确拷贝。

const source = {
  set foo(value) {
    console.log(value)
  },
}

const target2 = {}
Object.defineProperties(target2, Object.getOwnPropertyDescriptors(source))

Object.getOwnPropertyDescriptor(target2, 'foo')
// { get: undefined,
//   set: [Function: set foo],
//   enumerable: true,
//   configurable: true }

实例

浅拷贝一个对象

配合 Object.create() 方法,将对象属性克隆到一个新对象。

Object.create(Object.getPrototypeOf(obj), Object.getOwnPropertyDescriptors(obj))

创建子类

创建子类的典型方法是定义子类,将其原型设置为超类的实例,然后在该实例上定义属性。这么写很不优雅,特别是对于 getters 和 setter 而言。可以下面方式设置原型:

function superclass() {}
superclass.prototype = {
  // 在这里定义方法和属性
}
function subclass() {}
subclass.prototype = Object.create(
  superclass.prototype,
  Object.getOwnPropertyDescriptors({
    // 在这里定义方法和属性
  }),
)
Copyright © 零度实验室 2020 all right reserved,powered by Gitbook修订时间: 2021-07-02 10:46:52

results matching ""

    No results matching ""