在JavaScript中,最有效的深度克隆对象的方法是什么?

25 浏览
0 Comments

在JavaScript中,最有效的深度克隆对象的方法是什么?

此问题的答案是社区努力的结果。 编辑现有答案以改进此帖子。 它当前不接受新的答案或交互。

克隆JavaScript对象的最有效方法是什么?我看到过使用obj = eval(uneval(o));,但那是非标准的,只受Firefox支持

我做过像obj = JSON.parse(JSON.stringify(o));这样的事情,但怀疑其效率。

我也看过带有各种缺陷的递归复制函数。

我很惊讶没有规范的解决方案。

admin 更改状态以发布 2023年5月19日
0
0 Comments

本地深度克隆

现在有一个名为“结构化克隆”的 JS 标准,可以在 Node 11 及更高版本中实验性地工作,将在浏览器中实现,并且已经为现有系统提供了兼容性填充

structuredClone(value)

如果需要,首先加载兼容性填充:

import structuredClone from '@ungap/structured-clone';

有关详细信息,请参见此答案

旧版答案

带数据丢失的快速克隆-JSON.parse/stringify

如果您的对象中不使用 Date、函数、undefinedInfinity、正则表达式、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 模块库的一部分,每个模块只完成一个任务。让您的工具包轻松无罪。
0