在JavaScript中,最有效的深度克隆对象的方法是什么?
在JavaScript中,最有效的深度克隆对象的方法是什么?
此问题的答案是社区努力的结果。 编辑现有答案以改进此帖子。 它当前不接受新的答案或交互。
克隆JavaScript对象的最有效方法是什么?我看到过使用obj = eval(uneval(o));
,但那是非标准的,只受Firefox支持。
我做过像obj = JSON.parse(JSON.stringify(o));
这样的事情,但怀疑其效率。
我也看过带有各种缺陷的递归复制函数。
我很惊讶没有规范的解决方案。
admin 更改状态以发布 2023年5月19日
本地深度克隆
现在有一个名为“结构化克隆”的 JS 标准,可以在 Node 11 及更高版本中实验性地工作,将在浏览器中实现,并且已经为现有系统提供了兼容性填充。
structuredClone(value)
如果需要,首先加载兼容性填充:
import structuredClone from '@ungap/structured-clone';
有关详细信息,请参见此答案。
旧版答案
带数据丢失的快速克隆-JSON.parse/stringify
如果您的对象中不使用 Date
、函数、undefined
、Infinity
、正则表达式、Map、Set、Blob、FileList、ImageData、稀疏数组、类型化数组或其他复杂类型,则可以使用非常简单的一行代码深度克隆对象:
JSON.parse(JSON.stringify(object))
const a = { string: 'string', number: 123, bool: false, nul: null, date: new Date(), // stringified undef: undefined, // lost inf: Infinity, // forced to 'null' re: /.*/, // lost } console.log(a); console.log(typeof a.date); // Date object const clone = JSON.parse(JSON.stringify(a)); console.log(clone); console.log(typeof clone.date); // result of .toISOString()
有关基准测试,请参见Corban 的答案。
使用库进行可靠的克隆
由于克隆对象并不是易事(复杂类型、循环引用、函数等),大多数主要的库都提供了克隆对象的函数。不要重复造轮子 - 如果您已经在使用一个库,请检查它是否有一个对象克隆函数。例如:
- lodash -
cloneDeep
;可以通过lodash.clonedeep模块单独导入,如果您还没有使用提供深度克隆函数的库,那么它可能是您的最佳选择 - AngularJS -
angular.copy
- jQuery -
jQuery.extend(true, { }, oldObject)
;.clone()
只克隆 DOM 元素 - just library -
just-clone
;是一个零依赖 npm 模块库的一部分,每个模块只完成一个任务。让您的工具包轻松无罪。