JavaScriptにおける配列の深層コピーは、データの整合性を確保し、意図しない副作用を防ぐために非常に重要です。浅いコピーは参照のみを複製するのに対し、深層コピーはすべてのネストされた構造を含む完全に独立したコピーを作成します。この記事では、深層コピーを実現するためのいくつかの方法を検討し、それぞれの長所と短所を比較することで、特定のニーズに最適なアプローチを選択するのに役立ちます。
目次
浅いコピーと深いコピーの理解
JavaScriptでデータ構造をコピーする際には、浅いコピーと深いコピーの違いを理解することが重要です。浅いコピーは新しいオブジェクトを作成しますが、元の要素への参照でそれを埋めます。浅いコピー内のネストされた要素を変更すると、元のものも変更されます。逆に、深いコピーは、元のオブジェクトとそのすべてのネストされた構造の完全に独立したレプリカを作成します。深いコピーへの変更は元には影響せず、その逆も同様です。
structuredClone()
の使用
structuredClone()
メソッドは、深層コピーを作成するための現代的で効率的な方法です。現在のブラウザとNode.js環境で広くサポートされており、循環参照も適切に処理します。
const originalArray = [1, 2, [3, 4], { a: 5 }];
const deepCopyArray = structuredClone(originalArray);
deepCopyArray[2].push(5);
deepCopyArray[3].a = 10;
console.log("Original Array:", originalArray); // 変更なし
console.log("Deep Copy Array:", deepCopyArray); // 変更あり
この方法は、そのシンプルさと堅牢性から一般的に推奨されます。
JSON.parse()
とJSON.stringify()
の活用
このテクニックは、JSON.stringify()
を使用して配列をJSON文字列にシリアル化し、JSON.parse()
を使用してそれを新しい配列に逆シリアル化します。単純な配列には有効ですが、制限があります。
const originalArray = [1, 2, [3, 4], { a: 5 }];
const deepCopyArray = JSON.parse(JSON.stringify(originalArray));
deepCopyArray[2].push(5);
deepCopyArray[3].a = 10;
console.log("Original Array:", originalArray);
console.log("Deep Copy Array:", deepCopyArray);
制限事項:
- JSONでシリアル化可能なデータ型でのみ機能します。関数、日付、カスタムオブジェクトは正しく処理されない場合があります。
- 大きな配列では
structuredClone()
よりも効率が低い場合があります。
Lodashライブラリの利用
Lodashの_.cloneDeep()
関数は、堅牢な深層クローニングソリューションを提供します。ただし、外部依存関係が導入されます。
const _ = require('lodash'); // lodashのインストールが必要です: npm install lodash
const originalArray = [1, 2, [3, 4], { a: 5 }];
const deepCopyArray = _.cloneDeep(originalArray);
deepCopyArray[2].push(5);
deepCopyArray[3].a = 10;
console.log("Original Array:", originalArray);
console.log("Deep Copy Array:", deepCopyArray);
Lodashはさまざまなデータ型を効果的に処理しますが、プロジェクトの複雑さを増します。
最適な方法の選択
structuredClone()
は、効率性、幅広い互換性、使いやすさのバランスから、一般的に推奨されます。JSON.parse()/JSON.stringify()
は、JSON互換データを持つ基本的な配列に対するよりシンプルな代替手段です。Lodashは強力なソリューションを提供しますが、外部依存関係が必要です。最適な方法を選択する際には、プロジェクトのニーズと複雑さを考慮してください。