当前位置: 首页
前端开发
如何用 Object.getOwnPropertyDescriptors 完美克隆包含 Getter/Setter 的复杂对象

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

热心网友 时间: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。

同类文章
更多
HTML怎么做Performance度量_HTML performance.measure度量【收藏】

HTML怎么做Performance度量_HTML performance.measure度量【收藏】

performance measure:深入解析,它并非“一键测速”的万能工具 首先,必须明确一个核心要点:performance measure 并非一个能够自动完成所有性能测量的“黑盒”工具。它的本质是一个“时间差计算器”,其功能是精确计算出两个已定义标记点之间的时长。它本身并不主动采集任何原始

时间:2026-04-18 13:28
如何利用 MutationObserver 监控并防止恶意浏览器脚本修改网页中受法律保护的内容声明

如何利用 MutationObserver 监控并防止恶意浏览器脚本修改网页中受法律保护的内容声明

如何利用 MutationObserver 监控并防止恶意浏览器脚本修改网页中受法律保护的内容声明 在网站安全防护中,版权声明、法律条款等受法律保护的内容极易成为恶意脚本的攻击目标。如何有效监控并防止这些关键信息被篡改或隐藏?原生 JavaScript 提供的 MutationObserver AP

时间:2026-04-18 13:26
figure和figcaption标签的作用?HTML图文组合排版使用方法

figure和figcaption标签的作用?HTML图文组合排版使用方法

figure与figcaption标签详解:HTML语义化图文排版的核心用法 首先需要明确一个关键概念:figure 与 figcaption 这对HTML标签,其核心价值远不止于实现图文居中排列的视觉效果。它们的主要功能是向浏览器、搜索引擎以及屏幕阅读器等辅助技术传递清晰的语义信息:“请注意,这个

时间:2026-04-18 13:26
HTML中fieldset边框文字 HTML中fieldset标签legend对齐设置

HTML中fieldset边框文字 HTML中fieldset标签legend对齐设置

HTML5已废弃属性,须用CSS的text-align控制文字对齐;必须为首子元素以保障可访问性,且需配合视觉样式维持语义分组。 legend 文字对齐不能依赖已废弃的 align 属性 如果你仍在代码中使用 这类写法,请注意这已是过时的技术。HTML5 规范已明确废弃 align 属性。主流浏览器

时间:2026-04-18 13:24
如何将Bootstrap与ECharts图表库结合使用?

如何将Bootstrap与ECharts图表库结合使用?

如何将Bootstrap与ECharts图表库结合使用? 将Bootstrap的响应式栅格系统与ECharts强大的数据可视化图表结合,是构建现代化数据仪表盘的常见需求。然而,直接组合两者时,若处理不当,常会遇到图表不显示、尺寸错乱或响应失效等问题。本文将详解Bootstrap整合ECharts的三

时间:2026-04-18 12:53
热门专题
更多
刀塔传奇破解版无限钻石下载大全 刀塔传奇破解版无限钻石下载大全
洛克王国正式正版手游下载安装大全 洛克王国正式正版手游下载安装大全
思美人手游下载专区 思美人手游下载专区
好玩的阿拉德之怒游戏下载合集 好玩的阿拉德之怒游戏下载合集
不思议迷宫手游下载合集 不思议迷宫手游下载合集
百宝袋汉化组游戏最新合集 百宝袋汉化组游戏最新合集
jsk游戏合集30款游戏大全 jsk游戏合集30款游戏大全
宾果消消消原版下载大全 宾果消消消原版下载大全
  • 日榜
  • 周榜
  • 月榜
热门教程
更多
  • 游戏攻略
  • 安卓教程
  • 苹果教程
  • 电脑教程