JavaScriptにおけるシャローコピーとディープコピーの違い

JavaScriptは、データ型に応じて2通りの方法でコピーを処理します。

プリミティブ値(値によるコピー)

プリミティブ型には、stringnumberbooleansymbolbigIntnullが含まれます。 プリミティブ値をコピーすると、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に組み込まれている関数です。ネストされた構造を完璧に処理します。

メリット:

  • 高速でネイティブ。
  • DateRegExpMapを扱えます。

デメリット:

  • オブジェクトに関数やDOMノードが含まれている場合は失敗します。

2. JSON.parse(JSON.stringify())

これは、オブジェクトを一度文字列に変換し、再びオブジェクトに戻すという古い手法です。

なぜ避けるべきなのか:

  • undefinedMapSetInfinityなどのデータが失われます。
  • 特定の値が破損する可能性があります。

出典: https://dev.to/yogesh_992/shallow-copy-vs-deep-copy-in-java-script-explained-in-easiest-way-3dg5