What is the most efficient way to clone a JavaScript object? I've seen obj = eval(uneval(o)); being used, but that's non-standard and only supported by Firefox.

I've done things like obj = JSON.parse(JSON.stringify(o)); but question the efficiency.

I've also seen recursive copying functions with various flaws.
I'm surprised no canonical solution exists.

推荐答案

Native deep cloning

现在有了一个名为"structured cloning"的JS标准,它在Node 11和更高版本中实验性地工作,将在浏览器中使用,它有polyfills for existing systems个.

structuredClone(value)

如果需要,首先加载polyfill:

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

有关更多详细信息,请参见this answer.

Older answers

数据丢失的快速克隆——JSON.解析/字符串化

如果在对象中不使用Date、函数、undefinedInfinity、regexp、映射、集合、Blob、文件列表、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's answer.

使用库进行可靠克隆

由于克隆对象并不简单(复杂类型、循环引用、函数等),大多数主要库都提供克隆对象的函数.Don't reinvent the wheel-如果你已经在使用一个库,判断它是否有对象克隆功能.例如

ES6 (shallow copy)

为了完整性,请注意ES6提供了两种浅层复制机制:Object.assign()spread syntax. 它将所有可枚举的OWN属性的值从一个对象复制到另一个对象.例如:

var A1 = {a: "2"};
var A2 = Object.assign({}, A1);
var A3 = {...A1};  // Spread Syntax

Javascript相关问答推荐

不适用于 React 的 JSX 条件

如何将主 js 文件中的数组用于不同的 js 文件?

在包装函数中添加日志(log)

在javascript中转义双引号

如何在 React.js 中处理未知数量的状态变量?

视频在 chrome 中播放,但没有在 safari 浏览器中播放

如何去除三元运算符的重复代码?

有没有办法在Javascript中将只有hh:mm的字符串转换为日期

无法访问存储在 vue.js 中本地存储 [object Object] 中的 json 对象

React - 从子组件更新状态,然后根据状态做一些事情

正则表达式(Regex)不适用于坐标javascript的所有样本

在自定义钩子中创建一个数组是在每次状态更改时重新渲染值

如何使用递归函数构造 id/parentIds

受控形式:如果输入无效,则显示 div

document.getElementById().value - 覆盖或知道何时访问

如何将通常位于数据库中的数据保存到 SharePoint 文件夹或网站的根文件夹

React - 在不加载页面的情况下在 url 之间导航

将 SVG 转换为 PDF 时的奇怪输出 javascript mermaid.js 示例

悬停时未出现元素

有没有办法在 JS 中将一个键的值设置为与同一对象中另一个键的值相同?