The native deep copy of JS is coming——structuredClone

foreword

When it comes to deep copy of JS, two implementation methods may automatically appear in your mind:

  • JSON.parse(JSON.stringify(obj))

  • lodash's cloneDeep

Both of the above two deep copy methods have some disadvantages (which will be described in detail later in this article), so when learning the above deep copy methods, you may have thought about why the browser does not support native deep copy? This is not structuredClone here~ The deep copy API natively supported by the browser runtime

Disadvantages of JSON.parse(JSON.stringify(obj))

  • If your obj object has a circular reference, then this method will report an error

image

  • If your obj object has a Date object, this method will convert it into a string

image

  • If there are Set, Map, Regular, Error objects in your obj object, this method will convert them into empty object literals { }, if there is undefined, this method will directly ignore

image

See the execution results in the figure above, the objects of Set, Map, Regular, and Error have all become { }, and undefined has disappeared. . .

Possible risks of Lodash

image

image

Lodash's tree-shaking may be different from our thinking. If your project scaffolding does not handle this problem, and you do not pay attention to the way it is introduced, it will cause some performance loss.

To deal with tree-shaking of lodash, please refer to:

Import lodash on demand - One Leaf One Bodhi 22 - 博客园

Lodash: tree shaking

There are certain problems in the two common deep copy methods* (but they also have their own advantages. Readers should choose the appropriate deep copy method based on their own understanding of deep copy and the use of the scene. This article will briefly compare the three deep copy methods at the end. method)*, which leads to structuredClone, the protagonist of this article:

Introduction to structuredClone syntax

全局的 structuredClone() 方法使用结构化克隆算法将给定的值进行深拷贝

该方法还支持把原始值中的可转移对象转移到新对象,而不是把属性引用拷贝过去。 可转移对象与原始对象分离并附加到新对象;它们不可以在原始对象中访问被访问到。

——MDN

介绍 structuredClone 方法深拷贝的基础用法

const person = {
  name: "Timmy",
  gradutionDate: new Date('2017-06-17'),
  readingBooks: ['Dream of the Red Chamber']
}

const copied = structuredClone(person)
复制代码

在 console 控制台做个测试:

image

很多情况下,上述结果确实更符合我们开发者的使用心智!

structuredClone 深拷贝的能力如下:

structuredClone 不能做什么:

  • Function 对象是不能被结构化克隆算法复制的;如果你尝试这样子去做,这会导致抛出 DATA_CLONE_ERR 的异常。

  • 企图去克隆 DOM 节点同样会抛出 DATA_CLONE_ERR 异常。

  • 对象的某些特定参数也不会被保留

介绍 structuredClone 方法转移[可转移对象]的用法

语法:

structuredClone(value, { transfer })
复制代码

When the optional parameter transfer is passed to the structuredClone method, the transferable object can only be transferred without being cloned. The transfer makes the original object (properties in it) no longer usable.

var uInt8Array = new Uint8Array(1024 * 1024 * 16); // 16MB
for (var i = 0; i < uInt8Array.length; ++i) {
  uInt8Array[i] = i;
}
const transferred = structuredClone(uInt8Array, { transfer: [uInt8Array.buffer] });
console.log(uInt8Array.byteLength);  // 0
复制代码

Comparing three deep copy methods

  • The JSON.parse(JSON.stringify(obj)) method is easy to use and has good compatibility. If you are dealing with a deep copy of a simple data type, this method can be held

  • _.copyDeep has good compatibility and powerful functions. It will not report errors for Function types, but the disadvantage is that you need to pay attention to tree-shaking, otherwise there will be performance loss

  • The structuredClone method is natively supported by browsers, and it will report an error for the Function type, but the main disadvantage is compatibility issues:

    structuredClone method shim: github.com/ungap/struc…

Reference documents:

[1] Deep Cloning Objects in JavaScript, the Modern Way

[2] The latest HTML specification - structuredClone deep copy function, can it replace JSON or lodash? - Nuggets

[3] structuredClone() - Web development techniques | MDN

[4] Structured Cloning Algorithm - Web API Interface Reference | MDN

[5] Transferable Objects - Web API Interface Reference | MDN

Guess you like

Origin juejin.im/post/7193997944171790396