ES7 中如何使用 Object.getOwnPropertyDescriptors 来实现对象复制

在前端开发中,我们经常需要复制一个对象。ES6 提供了 Object.assign() 方法可以复制对象,但它有一些限制,比如不能复制不可遍历(non-enumerable)的属性,也不能复制访问器属性(accessors)等。ES7 中新增了 Object.getOwnPropertyDescriptors() 方法,可以在复制对象时避免这些限制。本文将详细介绍如何使用 Object.getOwnPropertyDescriptors() 来实现对象复制。

Object.getOwnPropertyDescriptors() 简介

Object.getOwnPropertyDescriptors() 方法返回指定对象所有自身属性(不包括继承属性)的属性描述符(包括 valuewritableenumerableconfigurable)。如果要拷贝一个对象并且需要复制其所有属性(包括不可遍历和访问器属性),可以使用该方法。

方法语法:

Object.getOwnPropertyDescriptors(obj)

其中,obj 是目标对象。

返回值是一个键值为属性名,值为属性描述符的对象。

实现对象复制

使用 Object.getOwnPropertyDescriptors() 的方法很简单,步骤如下:

  1. 创建一个空对象。
  2. 使用 Object.getOwnPropertyDescriptors() 方法获取源对象的所有属性描述符并将其赋值给目标对象。
  3. 返回目标对象。

代码实现:

function cloneObject(obj) {
  const clone = Object.create(Object.getPrototypeOf(obj))
  const descriptors = Object.getOwnPropertyDescriptors(obj)
  Object.defineProperties(clone, descriptors)
  return clone
}

这个函数返回 obj 的一个副本,包括所有属性(包括不可遍历和访问器属性)。如果要仅复制 obj 的可枚举属性,可以添加一个检查:

function cloneObject(obj) {
  const clone = Object.create(Object.getPrototypeOf(obj))
  const descriptors = Object.getOwnPropertyDescriptors(obj)
  Object.keys(descriptors).forEach(key => {
    const desc = descriptors[key]
    if (desc.enumerable) {
      Object.defineProperty(clone, key, desc)
    }
  })
  return clone
}

示例代码

const obj = {
  prop1: 'value1',
  prop2: 'value2',
  prop3: {
    subProp: 'subvalue'
  },
  [Symbol('hidden')]: 'hidden value',
  get accessor() {
    return this.prop1
  }
}

const clonedObj = cloneObject(obj)

console.log(clonedObj)
// {prop1: 'value1', prop2: 'value2', prop3: {subProp: 'subvalue'}, accessor: [Getter]}

console.log(clonedObj === obj)
// false

总结

使用 Object.getOwnPropertyDescriptors() 可以复制目标对象的所有属性,包括不可枚举和访问器属性。在编写代码时,我们应该优先考虑使用 Object.getOwnPropertyDescriptors() 来复制对象,以提高代码的可读性和可维护性。

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65910f9aeb4cecbf2d644829


纠错
反馈