内容来自 DOC https://q.houxu6.top/?s=在JavaScript中,最高效的方法来深度克隆一个对象是什么?
将JavaScript对象进行深度克隆的最有效方法是什么?我见过使用obj = eval(uneval(o));
,但这是非标准的做法,仅被Firefox支持。
我曾尝试过obj = JSON.parse(JSON.stringify(o));
,但对效率有所质疑。
我还看到过各种缺陷的递归复制函数。
我很惊讶居然没有标准的解决方法。
原生深度克隆
现在有一个名为"结构化克隆"的JavaScript标准,它实验性地在Node 11及更高版本中可用,将登陆浏览器,并且已经有了现有系统的polyfills。
structuredClone(value)
如果需要,先加载polyfill:
import structuredClone from '@ungap/structured-clone';
有关更多详细信息,请参阅此答案。
旧答案
带有数据丢失的快速克隆 - JSON.parse/stringify
如果你的对象中不包含Date
、函数、undefined
、Infinity
、RegExps、Maps、Sets、Blobs、FileLists、ImageDatas、稀疏数组、类型化数组或其他复杂类型,那么一个简单的一行代码就可以深度克隆一个对象:
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
;是一个库的组成部分,具有零依赖性,只做一件事。
适用于任何场合的免罪实用工具。