在前端开发中,我们经常需要复制一个对象。ES6 提供了 Object.assign()
方法可以复制对象,但它有一些限制,比如不能复制不可遍历(non-enumerable)的属性,也不能复制访问器属性(accessors)等。ES7 中新增了 Object.getOwnPropertyDescriptors()
方法,可以在复制对象时避免这些限制。本文将详细介绍如何使用 Object.getOwnPropertyDescriptors()
来实现对象复制。
Object.getOwnPropertyDescriptors()
简介
Object.getOwnPropertyDescriptors()
方法返回指定对象所有自身属性(不包括继承属性)的属性描述符(包括 value
、writable
、enumerable
和 configurable
)。如果要拷贝一个对象并且需要复制其所有属性(包括不可遍历和访问器属性),可以使用该方法。
方法语法:
Object.getOwnPropertyDescriptors(obj)
其中,obj
是目标对象。
返回值是一个键值为属性名,值为属性描述符的对象。
实现对象复制
使用 Object.getOwnPropertyDescriptors()
的方法很简单,步骤如下:
- 创建一个空对象。
- 使用
Object.getOwnPropertyDescriptors()
方法获取源对象的所有属性描述符并将其赋值给目标对象。 - 返回目标对象。
代码实现:
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