在JavaScript中,最高效的方法来深度克隆一个对象是什么?

发布时间 2023-10-11 23:20:13作者: 小满独家

内容来自 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、函数、undefinedInfinity、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;是一个库的组成部分,具有零依赖性,只做一件事。
    适用于任何场合的免罪实用工具。