ホームページ  >  記事  >  ウェブフロントエンド  >  JavaScript におけるシャロー コピーとディープ コピー

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

Mary-Kate Olsen
Mary-Kate Olsenオリジナル
2024-11-25 05:32:17362ブラウズ

Shallow Copy vs. Deep Copy in JavaScript

概要

JavaScript では、オブジェクトまたは配列のコピーは、浅いコピーと深いコピーに分類できます。複雑なデータ構造、特にネストされたオブジェクトや配列を含むデータ構造を扱う場合、この違いを理解することが重要です。

このガイドでは、これらの概念、その特性、実装方法、およびそれぞれをいつ使用するかについて説明します。

1. 浅いコピー

定義
浅いコピーでは、オブジェクトまたは配列の最上位プロパティの複製が作成されます。ただし、ネストされたオブジェクトまたは配列の場合は、参照のみがコピーされ、実際のデータはコピーされません。

特徴

  • プロパティまたは要素の最初のレベルのみをコピーします。
  • ネストされたオブジェクトまたは配列は、元のオブジェクト/配列と参照を共有します。
  • 単純な構造では軽量で効率的ですが、ネストされたデータの独立した複製には適していません。

1.1 Object.assign() の使用

const original = { a: 1, b: { c: 2 } };
const shallowCopy = Object.assign({}, original);

shallowCopy.b.c = 42; 
console.log(original.b.c); // OUTPUT: 42 (The original object also affected due to shared reference)

1.2 スプレッド演算子 (...) の使用

const original = { a: 1, b: { c: 2 } };
const shallowCopy = { ...original };

shallowCopy.b.c = 90;
console.log(original.b.c); // OUTPUT: 90

1.3 配列メソッド (slice、concat) での浅いコピーの例を見てみましょう

const original = [1, 2, [3, 4]];
const shallowCopy = original.slice();

shallowCopy[2][0] = 10; 
console.log(original[2][0]); // OUTPUT: 10

2.ディープコピー

定義
ディープ コピーは、オブジェクトまたは配列の完全に独立した複製を作成します。ネストされた構造を含むすべてのレベルが再帰的にコピーされます。コピーされた構造を変更しても元の構造には影響しません。また、その逆も同様です。

特徴

  • 構造のすべてのレベルを再帰的にコピーします。
  • ネストされたオブジェクトまたは配列は、元のオブジェクトまたは配列から独立しています。
  • 浅いコピーよりも計算が重い。

2.1 JSON.stringify() と JSON.parse() の使用

  • オブジェクトを JSON 文字列に変換し、その後新しいオブジェクトに戻します。
  • 制限事項: 関数、日付、正規表現、または循環参照は処理されません。
const original = { a: 1, b: { c: 2 } };
const deepCopy = JSON.parse(JSON.stringify(original));

deepCopy.b.c = 42;
console.log(original.b.c); // OUTPUT: 2 (original remains unaffected)

2.2 StructuredClone() の使用
循環参照と Date などの特別なオブジェクトをサポートするディープ コピーの最新の方法。

const original = { a: 1, b: { c: 2 }, date: new Date() };
const deepCopy = structuredClone(original);

deepCopy.b.c = 42;
console.log(original.b.c); // OUTPUT: 2
console.log(original.date === deepCopy.date); // FALSE

2.3 カスタム再帰関数の使用
複雑なケースを手動で処理するための柔軟なソリューション。

function deepCopy(obj) {
  if (obj === null || typeof obj !== "object") return obj; 

  if (Array.isArray(obj)) return obj.map(deepCopy); 

  const copy = {};
  for (const key in obj) {
    if (obj.hasOwnProperty(key)) {
      copy[key] = deepCopy(obj[key]);
    }
  }
  return copy;
}

const original = { a: 1, b: { c: 2 } };
const deepCopyObj = deepCopy(original);

deepCopyObj.b.c = 42;
console.log(original.b.c); // OUTPUT: 2

3. それぞれをいつ使用するか?

浅いコピー

  • 入れ子構造のないフラットなオブジェクトまたは配列の場合。
  • パフォーマンスが重要であり、ネストされたオブジェクトの共有参照が許容される場合。

ディープコピー

  • 複雑で深くネストされたオブジェクト/配列の場合。
  • コピーとオリジナルの間に真の独立性が必要な場合。

4. まとめ

浅いコピー

  • シンプルで効率的です。
  • フラットな構造、または共有参照が許容される場合に適しています。

ディープコピー

  • 堅牢で完全な独立性を保証します。
  • 深くネストされた構造または複雑な構造に最適です。

これは、JavaScript におけるオブジェクトの浅いコピーと深いコピーについて詳しく説明しています。ユースケースとパフォーマンス要件に基づいて、適切な方法を選択してください。

以上がJavaScript におけるシャロー コピーとディープ コピーの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。