Object.getOwnPropertyDescriptors 可完整克隆属性描述符,包括 value、writable、enumerable、configurable 及 get/set 访问器,但仅复制结构不深拷贝值或函数引用。

直接用 Object.getOwnPropertyDescriptors 获取源对象所有自有属性的完整描述符,再配合 Object.defineProperties 将其定义到新对象上,就能实现“克隆属性描述符”——包括 value、writable、enumerable、configurable,甚至 get/set 访问器,而不仅仅是值。
获取并复用完整描述符
该方法返回一个对象,其每个键对应源对象的一个自有属性名,值为该属性的完整属性描述符(descriptor)。它不遍历原型链,只处理对象自身拥有的属性。
- 对普通数据属性,会保留
value、writable、enumerable、configurable - 对 getter/setter 属性,会保留
get、set、enumerable、configurable,但不包含value和writable - 结果可直接传给
Object.defineProperties,无需额外转换
基础克隆示例(含访问器)
下面代码克隆了一个带不可写、不可枚举、不可配置数据属性,以及一个 getter 的对象:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
const source = {
a: 1,
get b() { return this.a * 2; }
};
<p>Object.defineProperty(source, 'a', {
writable: false,
enumerable: false,
configurable: false
});</p><p>Object.defineProperty(source, 'b', {
enumerable: true,
configurable: false
});</p><p>const descriptors = Object.getOwnPropertyDescriptors(source);
const clone = {};
Object.defineProperties(clone, descriptors);</p><p>// 验证:clone.a 不可写,clone.b 是 getter,且枚举行为一致
console.log(clone.a); // 1
clone.a = 2;
console.log(clone.a); // 仍为 1(writable: false 生效)
console.log('b' in clone); // true(enumerable: true)
注意深拷贝与引用问题
Object.getOwnPropertyDescriptors 只复制属性的“结构”(描述符),不递归克隆嵌套对象或函数引用:
立即学习“Java免费学习笔记(深入)”;
- 如果
value是对象或数组,克隆后仍是同一引用,不是深拷贝 - 如果
get或set是函数,克隆后指向同一个函数实例 - 如需深克隆值,需在拿到 descriptor 后手动处理
value字段(例如用 structuredClone 或递归复制)
兼容性与替代方案
该 API 自 ES2017 起被广泛支持(Chrome 54+、Firefox 52+、Node.js 7.0+)。若需兼容旧环境:
- 可用
Object.keys+Object.getOwnPropertyDescriptor手动遍历拼接 descriptors 对象 - 但无法一次性获取所有属性(包括不可枚举的),需改用
Object.getOwnPropertyNames+Object.getOwnPropertySymbols组合 - 访问器属性的
get/set在旧引擎中可能因函数引用丢失上下文,需谨慎测试

















