序文
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 - 博客园
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 控制台做个测试:
很多情况下,上述结果确实更符合我们开发者的使用心智!
structuredClone 深拷贝的能力如下:
-
Copy 无限嵌套的对象和数组
-
Copy 循环引用
-
Copy 如下数据类型:
仅支持以下 Error 类型:Error、EvalError、RangeError、ReferenceError、SyntaxError、TypeError、URIError(或其它会被设置为 Error 的)。
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