JavaScriptにおけるシャローコピーとディープコピーの違い
JavaScriptは、データ型に応じて2通りの方法でコピーを処理します。
プリミティブ値(値によるコピー)
プリミティブ型には、string、number、boolean、symbol、bigInt、nullが含まれます。
プリミティブ値をコピーすると、JavaScriptはメモリ内に新しい独立したバージョンを作成します。
例:
let a = 10;
let b = a;
b = 20;
結果: aは10のままです。
非プリミティブ値(参照によるコピー)
オブジェクトや配列は動作が異なります。これらは参照を使用します。 オブジェクトをコピーする場合、メモリ上の位置へのポインタのみがコピーされます。
例:
let original = { name: "YOO" };
let copy = original;
copy.name = "NEW";
結果: original.nameは現在"NEW"になっています。
違い:シャローコピー vs ディープコピー
シャローコピー(浅いコピー)は、オブジェクトのトップレベルのみをコピーします。オブジェクトにネストされたオブジェクトがある場合、それらは依然として元のネストされた参照を指しています。 ディープコピー(深いコピー)は、すべての値が新しい、完全に新しいオブジェクトを作成します。
ピザに例えて考えてみましょう:
- シャローコピー: あなたと友人が1枚のピザを分け合っています。友人が1スライス食べると、あなたにとってもピザが少なくなります。
- ディープコピー: 二人とも別々のピザを持っています。友人が1スライス食べても、あなたのピザは変わりません。
シャローコピーの方法
スプレッド演算子 (...) を使用してシャローコピーを作成できます。
let original = { name: "YOO", details: { age: 22 } };
let copy = { ...original };
注意: original.details.ageを変更すると、copy.details.ageも変更されます。これがシャローコピーの罠です。
ディープコピーの方法
1. structuredClone()
これは最新のブラウザやNode.jsに組み込まれている関数です。ネストされた構造を完璧に処理します。
メリット:
- 高速でネイティブ。
Date、RegExp、Mapを扱えます。
デメリット:
- オブジェクトに関数やDOMノードが含まれている場合は失敗します。
2. JSON.parse(JSON.stringify())
これは、オブジェクトを一度文字列に変換し、再びオブジェクトに戻すという古い手法です。
なぜ避けるべきなのか:
undefined、Map、Set、Infinityなどのデータが失われます。- 特定の値が破損する可能性があります。
出典: https://dev.to/yogesh_992/shallow-copy-vs-deep-copy-in-java-script-explained-in-easiest-way-3dg5
