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相关问答推荐

根据总价格对航班优惠数组进行排序并检索前五个结果- Angular HTTP请求

确定MutationRecord中removedNodes的索引

没有输出到带有chrome.Devtools扩展的控制台

IMDB使用 puppeteer 加载更多按钮(nodejs)

硬币兑换运行超时

我开始使用/url?q=使用Cheerio

了解Node.js中的EventEums和浏览器中的addEventEums之间的关系

Mongoose post hook在使用await保存时不返回Postman响应

如何让npx在windows中运行js脚本?

为什么我的自定义元素没有被垃圾回收?

变量在导入到Vite中的另一个js文件时成为常量.

自定义图表工具提示以仅显示Y值

处理app.param()中的多个参数

bootstrap S JS赢得了REACT中的函数/加载

Chart.js Hover线条在鼠标离开时不会消失

在将元素追加到DOM之前,createElement()是否会触发回流?混淆abt DocumentFragment行为

是否有静态版本的`instanceof`?

我如何才能让p5.js在不使用实例模式的情况下工作?

使用jQuery每隔几秒钟突出显示列表中的不同单词

我在JS代码中收到超过最大调用堆栈大小的错误,但我找不到原因.有谁能帮我搬一下吗?