首页 游戏 软件 资讯 排行榜 专题
首页
前端开发
如何用 Object.getOwnPropertyDescriptors 完美克隆包含 Getter/Setter 的复杂对象

如何用 Object.getOwnPropertyDescriptors 完美克隆包含 Getter/Setter 的复杂对象

热心网友
25
转载
2026-04-18

如何用 Object.getOwnPropertyDescriptors 完美克隆包含 Getter/Setter 的复杂对象

如何用 Object.getOwnPropertyDescriptors 完美克隆包含 Getter/Setter 的复杂对象

免费影视、动漫、音乐、游戏、小说资源长期稳定更新! 👉 点此立即查看 👈

Object.getOwnPropertyDescriptors 为什么能拿到 getter/setter

许多开发者存在一个普遍的误解,认为 Object.assign 或展开运算符 {...obj} 可以实现对象的完全复制。实际上,这两种方法仅复制属性的“值”,对于访问器属性(即包含 getset 函数的属性)则完全失效,因为这些访问器函数本身不会被遍历和复制。

解决这一问题的核心在于 Object.getOwnPropertyDescriptors 方法。它返回的不是属性值,而是每个属性的完整描述符对象。这个描述符对象包含了 getsetenumerableconfigurablewritable 等所有元数据。因此,它是精确复制访问器属性行为的唯一可靠途径,也是实现深度克隆的关键步骤。

克隆时必须用 Object.defineProperties 而非 Object.assign

如果错误地使用 Object.assign 进行克隆,会发生什么?它会将源对象的 getter 函数当作普通函数立即调用一次,然后将返回值作为一个静态的、不可变的数据属性赋值给目标对象。同时,setter 函数会完全丢失,导致克隆后的对象失去响应式能力。

正确的克隆流程是:首先使用 Object.getOwnPropertyDescriptors 获取源对象的所有属性描述符,然后通过 Object.defineProperties 方法将这些描述符精确地应用到新的空对象上,从而实现属性的“复刻”,包括其访问器行为:

const source = {
  _x: 10,
  get x() { return this._x * 2; },
  set x(v) { this._x = v / 2; }
};

const descriptors = Object.getOwnPropertyDescriptors(source);
const clone = Object.defineProperties({}, descriptors);

// ✅ 正确:clone.x 是响应式的访问器属性,修改 clone.x 会触发 setter
// ❌ 错误:Object.assign({}, source) 得到的是 { x: 20 } —— 一个静态值,无访问器功能

深层克隆需递归处理,但 descriptor 不含原型链信息

需要明确一个关键点:Object.getOwnPropertyDescriptors 仅作用于对象自身的(own)属性,不包含从原型链继承而来的属性,也不处理对象内部嵌套的复杂数据结构。因此,要实现一个健壮的深克隆函数,必须引入递归逻辑。

实现深度克隆的递归思路如下:

  • 对于待克隆的普通对象(非 null),首先调用 Object.getOwnPropertyDescriptors 获取其所有自身属性的描述符。
  • 遍历每个描述符,对其 value 字段进行判断:如果该值本身是对象或数组,则需要对这个值进行递归克隆,并将克隆结果作为新的 value
  • 对于描述符中的 getset 函数引用,应直接保留,无需也无法进行深克隆。
  • 特别注意:Object.defineProperties 只负责定义属性,不会自动设置对象的原型链。如果需要完整克隆,应在定义属性后,使用 Object.setPrototypeOf(clone, Object.getPrototypeOf(source)) 来显式设置克隆对象的原型。

容易漏掉的三个坑

理解了基本原理后,在实际编码中仍需警惕以下几个常见陷阱,它们常常导致克隆结果与预期不符:

  • 属性特性被忽略:属性描述符中的 enumerable(可枚举性)和 configurable(可配置性)等特性默认值为 false。如果源对象的某个属性这些特性为 true,但在克隆时未正确传递,克隆后的属性可能会变得不可枚举(例如在 for...in 循环中不可见)或不可删除。
  • Symbol 键被遗忘Object.getOwnPropertyDescriptors 默认只返回字符串键的属性描述符。对于使用 Symbol 作为键名的属性,必须额外使用 Object.getOwnPropertySymbols 方法获取其描述符,并将其合并到克隆流程中,否则这些属性会丢失。
  • 只读访问器被篡改:如果源对象定义了一个只有 get 而没有 set 的只读访问器属性,克隆后理应保持其只读特性。然而,如果在调用 Object.defineProperties 时错误地传递了 set: undefined,JavaScript 引擎会将其静默转换为一个普通的、可写的数据属性,从而破坏了原有的只读约束。

总而言之,实现一个“完美”的复杂对象克隆,并非依赖某个单一的 API 就能完成。它要求开发者深刻理解属性描述符的完整结构,并在使用 Object.defineProperties 时,一丝不苟地保留每个描述符字段的原始语义。任何细微的疏忽,都可能在后续的属性修改、遍历或特性检查中暴露问题,导致克隆对象行为异常。

来源:https://www.php.cn/faq/2339779.html
免责声明: 游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。

相关攻略

全国爱牙日横幅标语150句
职业与学业
全国爱牙日横幅标语150句

每年9月20日的全国爱牙日,其意义远不止于一个简单的纪念日。它更像一个年度提醒,一个全民总动员的号角,核心目标非常明确:唤醒公众对口腔健康的重视,推动良好卫生习惯的养成,从而从源头上预防各类口腔疾病。那么,在这个特别的日子里,哪些横幅标语既能传递核心信息,又朗朗上口、深入人心呢?下面这份精心整理的“

热心网友
04.18
怎么把iphone照片导入新iphone?零失败全攻略,看完就会
电脑教程
怎么把iphone照片导入新iphone?零失败全攻略,看完就会

对于许多人而言,照片不仅是图像,更是承载珍贵回忆与情感的数字资产。因此,在更换新iPhone时,如何安全、完整地转移这些照片成为首要关切。那么,如何将iPhone照片导入新iPhone?别着急,本文将为你系统梳理六种主流方案,并提供关键避坑指南,确保你的数字记忆无缝迁移。 一、iPhone照片导入新

热心网友
04.18
如何用 Object.getOwnPropertyDescriptors 完美克隆包含 Getter/Setter 的复杂对象
前端开发
如何用 Object.getOwnPropertyDescriptors 完美克隆包含 Getter/Setter 的复杂对象

如何用 Object getOwnPropertyDescriptors 完美克隆包含 Getter Setter 的复杂对象 Object getOwnPropertyDescriptors 为什么能拿到 getter setter 许多开发者存在一个普遍的误解,认为 Object assign

热心网友
04.18
小学励志班级口号
职业与学业
小学励志班级口号

口号的力量:不止于引导,更在于塑造 口号,从来都不只是简单的几个字。它自带倾向,充满能量,其引导和鼓动的价值,在当今快速发展的经济社会中愈发凸显,早已成为营销乃至团队建设中不可或缺的战略工具。为了给大家提供更丰富的灵感,我们特意在口号频道(www liuxue86 com kouhao )汇集了大量

热心网友
04.18
企业公司口号模板
职业与学业
企业公司口号模板

企业公司口号模板:精选团队激励标语大全 一句优秀的企业口号,不仅是团队精神的凝练表达,更是市场冲锋的号角与品牌形象的宣言。它能有效提升团队凝聚力、激发员工斗志,并在客户心中留下深刻印象。本文为您精心整理了一系列极具冲击力与团队感的企业口号模板,风格多样且易于套用,旨在为您的团队文化建设与市场品牌推广

热心网友
04.18

最新APP

宝宝过生日
宝宝过生日
应用辅助 04-07
台球世界
台球世界
体育竞技 04-07
解绳子
解绳子
休闲益智 04-07
骑兵冲突
骑兵冲突
棋牌策略 04-07
三国真龙传
三国真龙传
角色扮演 04-07

热门推荐

怎么参与现货网格?币安震荡行情自动买卖设置
web3.0
怎么参与现货网格?币安震荡行情自动买卖设置

现货网格交易终极指南:在币安高效捕捉震荡行情利润 在加密货币市场,震荡行情占据了大部分交易时间。对于希望实现自动化套利的交易者而言,现货网格交易无疑是一种高效策略。本文将为您提供一份详尽的币安网格交易设置教程,从币对选择到风控配置,手把手教您搭建一个稳健的自动化交易系统,旨在提升资金利用效率,在波动

热心网友
04.18
如何用 Object.getOwnPropertyDescriptors 完美克隆包含 Getter/Setter 的复杂对象
前端开发
如何用 Object.getOwnPropertyDescriptors 完美克隆包含 Getter/Setter 的复杂对象

如何用 Object getOwnPropertyDescriptors 完美克隆包含 Getter Setter 的复杂对象 Object getOwnPropertyDescriptors 为什么能拿到 getter setter 许多开发者存在一个普遍的误解,认为 Object assign

热心网友
04.18
Flowlu 2.0
AI
Flowlu 2.0

Flowlu 2 0是什么 如果说管理一家公司时,手边需要同时打开十几个软件窗口,那效率恐怕会大打折扣。而Flowlu 2 0要解决的,正是这个痛点。它本质上是一款All-In-One的全能型业务管理平台,由Flowlu团队精心打造。其目标很明确:帮助公司将散落在各处的运营环节——无论是项目管理、客

热心网友
04.18
OKX永续合约新手玩法及操作步骤详解2026
web3.0
OKX永续合约新手玩法及操作步骤详解2026

永续合约新手完全指南:从零基础到安全实战 在Web3的金融衍生品世界中,永续合约以其无到期日和高资金效率的特点,成为众多交易者的核心工具。然而,其独特的机制也伴随着显著风险。对于新手而言,透彻理解其运作原理并建立严格的风控体系,是迈向成功交易的第一步。本文将深入解析永续合约的核心机制,并提供一套完整

热心网友
04.18
Debian漏洞利用趋势
网络安全
Debian漏洞利用趋势

Debian安全态势深度解析:漏洞趋势与实战防护全攻略 在开源操作系统领域,Debian以其卓越的稳定性和公认的安全性,成为全球服务器与桌面环境的优先选择。然而,随着其应用规模的持续扩大,系统面临的安全威胁也日趋复杂与多样化。对于系统管理员和运维人员而言,深入理解Debian的漏洞利用现状与演变趋势

热心网友
04.18