JS のネイティブ ディープ コピーが登場します—structuredClone

序文

JS のディープ コピーに関して言えば、次の 2 つの実装方法が自動的に頭に浮かびます。

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

  • lodash の cloneDeep

上記の 2 つのディープ コピーの方法にはどちらもいくつかの欠点があります (詳細はこの記事の後半で説明します)。上記のディープ コピーの方法を学ぶとき、ブラウザーがネイティブのディープ コピーをサポートしていない理由を考えたことがあるかもしれません。これは構造化されていませんここにクローンを作成します~ ブラウザランタイムによってネイティブにサポートされているディープコピー API

JSON.parse(JSON.stringify(obj)) のデメリット

  • obj オブジェクトに循環参照がある場合、このメソッドはエラーを報告します。

画像

  • obj オブジェクトに Date オブジェクトがある場合、このメソッドはそれを文字列に変換します

画像

  • obj オブジェクトに Set、Map、Regular、Error オブジェクトがある場合、このメソッドはそれらを空のオブジェクト リテラル { } に変換します。未定義のオブジェクトがある場合、このメソッドは直接無視します

画像

上図の実行結果を見ると、Set、Map、Regular、Error のオブジェクトがすべて { } になり、undefined が消えています。. .

ロダッシュの考えられるリスク

画像

画像

Lodash のツリー シェイキングは、私たちの考えとは異なる場合があります. プロジェクトのスキャフォールディングがこの問題を処理できず、導入方法に注意を払わないと、パフォーマンスが低下する可能性があります.

lodash のツリー シェーキングに対処するには、以下を参照してください。

lodash をオンデマンドでインポート - One Leaf One Bodhi 22 - 博客园

Lodash: 木の揺れ

2 つの一般的なディープ コピー方式には特定の問題があります* (ただし、それぞれに利点もあります。読者は、ディープ コピーとシーンの使用に関する独自の理解に基づいて、適切なディープ コピー方式を選択する必要があります。この記事では、最後に 3 つのディープ コピー メソッド。

構造化クローン構文の紹介

全局的 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 })
复制代码

オプションのパラメーター transfer がstructuredClone メソッドに渡されると、転送可能複製されずに転送されるだけです。転送により、元のオブジェクト (その中のプロパティ) は使用できなくなります。

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
复制代码

3 つのディープ コピー方法の比較

  • JSON.parse(JSON.stringify(obj)) メソッドは使いやすく互換性が良い. 単純なデータ型のディープコピーを扱う場合はこのメソッドを保持できる.

  • _.copyDeep は優れた互換性と強力な関数を備えています. Function 型のエラーは報告されませんが, 欠点はツリー シェイキングに注意する必要があることです, そうしないとパフォーマンスが低下します.

  • structureClone メソッドはブラウザでネイティブにサポートされており、Function タイプのエラーが報告されますが、主な欠点は互換性の問題です。

    structuredClone メソッド shim: github.com/ungap/struc…

参考文献:

[1] JavaScript でのオブジェクトのディープ クローニング、最新の方法

[2]最新のHTML仕様~structuredCloneのディープコピー機能、JSONやlodashの代わりになるのか~ ナゲッツ

[3] structureClone() - Web 開発テクニック | MDN

[4]構造化クローニングアルゴリズム - Web API インターフェイスリファレンス | MDN

[5]転送可能なオブジェクト - Web API インターフェイスリファレンス | MDN

おすすめ

転載: juejin.im/post/7193997944171790396