在 JavaScript 中深度克隆对象的最有效方法是什么?
技术问答
388 人阅读
|
0 人回复
|
2023-09-11
|
我做过类似obj = JSON.parse(JSON.stringify(o));但是质疑效率。
& d) x6 e9 K; Q, P4 p. A我还看到了各种缺陷的递归复制函数。+ H$ O2 v5 w& b `( U5 L
我很惊讶没有标准化的解决方案。& L f- n1 t2 U V4 e, ^. g
! F: U1 C- h* h, R 解决方案: * P4 `! O) p3 F6 O0 C0 w
Native deep cloning现在有个名字structured cloning的 JS 标准,它在 Node 11 及更高版本进行实验性工作,将登录浏览器,并有适合现有系统的 polyfill。
% K1 U8 d* F1 h2 I7 SstructuredClone(value)! U0 h, `% L/ W$ A" |- |: x
如有必要,先加载 polyfill:4 C- o% O9 a, r4 c
import structuredClone from '@ungap/structured-clone';# L: e" U5 w5 W8 B
较旧的答案数据丢失的快速克隆 - JSON.parse/stringify如果不使用DateS,功能,undefined,Infinity,文件列表,正则表达式,地图,集合,斑点,ImageDatas,在稀疏数组、类型化数组或其他复杂类型的对象中,衬垫深克隆的简单对象是:
! _! m, q9 g# u* |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 objectconst clone = JSON.parse(JSON.stringify(a));console.log(clone);console.log(typeof clone.date); // result of .toISOString()$ a& r" Y* @# `+ ]
使用library可靠克隆由于克隆对象不容易(复杂类型、循环引用、函数等),大多数主要都提供了克隆对象的函数。不要重新发明轮子- 如果您已经在使用库,请检查它是否具有对象克隆功能。 X% z7 G n m5 `6 }9 o. o
lodash - cloneDeep; 可以通过lodash.clonedeep单独导入模块。如果您还没有使用提供深度克隆功能的库,它可能是您的最佳选择* M# X* l# Q4 \" ^" e1 d6 t% F
AngularJS - angular.copy- G( x6 Y5 P: d0 h1 }4 u
jQuery - jQuery.extend(true,{ },oldObject); .clone()只克隆 DOM 元素
6 A4 X( t1 ^, A7 t( c& Ejust library - just-clone; 零依赖 npm 模块库的一部分。适用于各种场合的无罪公用事业。ES6(shallow copy)请注意 起见,请注意 ES6 提供了两种浅拷贝机制:Object.assign() 和 spread syntax. 。它将所有可枚举属性的值从一个对象复制到另一个对象。
/ s8 R* ~! m: B1 `- }var A1 = {a: "2"};var A2 = Object.assign({},A1);var A3 = {...A / Spread Syntax
, [: [1 b+ B' n7 t+ { |
|
|
|
|
|