配列やオブジェクトのコピー操作 | イミュータビリティ | JavaScript 超完全入門 基本から発展までのすべて

スポンサーリンク
スポンサーリンク

配列やオブジェクトのコピー操作とは?

JavaScriptで配列やオブジェクトを操作する際、コピーを作成して操作することが重要です。コピー操作を使うことで、元のデータに影響を与えずに安全に変更を加えることができます。

コピーの種類:浅いコピーと深いコピー

配列やオブジェクトのコピーには、浅いコピー(Shallow Copy)深いコピー(Deep Copy)の2つの方法があります。それぞれの特徴を以下の表にまとめました。

種類 説明
浅いコピー 元のデータ構造の参照をそのままコピーする。ネストされたオブジェクトや配列は参照を共有する。
深いコピー すべての階層にわたってオブジェクトや配列を完全に複製する。ネストされたオブジェクトや配列も新しいコピーとして作成される。

浅いコピーの方法

JavaScriptでは、配列やオブジェクトの浅いコピーを作成するいくつかの方法があります。代表的なものにObject.assignやスプレッド構文があります。

Object.assignを使った浅いコピー

Object.assignメソッドを使うことで、浅いコピーを作成することができます。

const originalObject = { 
    name: 'Alice', 
    age: 25 
};
const shallowCopy = Object.assign({}, originalObject);

console.log(originalObject);
console.log(shallowCopy);

shallowCopy.age = 26;
console.log(originalObject.age);

出力: { name: 'Alice', age: 25 }
出力: { name: 'Alice', age: 25 }
出力: 25 (元のオブジェクトは変更されない)

この例では、Object.assignを使ってoriginalObjectの浅いコピーを作成しています。コピーを変更しても、元のオブジェクトには影響がありません。

スプレッド構文を使った浅いコピー

スプレッド構文を使用すると、簡潔に浅いコピーを作成できます。

const shallowCopy2 = { ...originalObject };
shallowCopy2.name = 'Bob';

console.log(originalObject);
console.log(shallowCopy2);

出力: { name: 'Alice', age: 25 }
出力: { name: 'Bob', age: 25 }

スプレッド構文では、オブジェクトや配列を展開し、新しいコピーを作成することが可能です。

配列に対する浅いコピーの例

配列もオブジェクトと同様に浅いコピーを作成することができます。

const originalArray = [1, 2, 3];
const shallowCopyArray = [...originalArray];

shallowCopyArray.push(4);

console.log(originalArray);
console.log(shallowCopyArray);

出力: [1, 2, 3]
出力: [1, 2, 3, 4]

スプレッド構文を使って配列の浅いコピーを作成し、コピーに要素を追加しても元の配列には影響がありません。

深いコピーの方法

浅いコピーでは、オブジェクトや配列のネストされた要素は元のデータと参照を共有しています。これを解決するために、深いコピーが必要です。深いコピーを行うための一般的な方法の一つに、JSON.stringifyJSON.parseを組み合わせる方法があります。

JSONメソッドを使った深いコピー

以下の例では、JSON.stringifyでオブジェクトを文字列化し、それをJSON.parseで再度オブジェクトに戻すことで、深いコピーを実現しています。

const nestedObject = { 
    name: 'Alice', 
    address: { city: 'Tokyo', zip: 100 } 
};
const deepCopy = JSON.parse(JSON.stringify(nestedObject));

deepCopy.address.city = 'Osaka';

console.log(nestedObject);
console.log(deepCopy);

出力: { name: 'Alice', address: { city: 'Tokyo', zip: 100 } }
出力: { name: 'Alice', address: { city: 'Osaka', zip: 100 } }

この方法では、ネストされたaddressオブジェクトも新しくコピーされているため、元のオブジェクトに影響を与えることなくデータを変更できます。

ライブラリを使った深いコピー

JavaScriptでは、深いコピーを簡単に行うためのライブラリがいくつか存在します。その中でも、LodashcloneDeep関数が非常に便利です。

Lodashを使った深いコピーの例

const _ = require('lodash');

const deepCopyWithLodash = _.cloneDeep(nestedObject);
deepCopyWithLodash.address.zip = 200;

console.log(nestedObject); 
console.log(deepCopyWithLodash);

出力: { name: 'Alice', address: { city: 'Tokyo', zip: 100 } }
出力: { name: 'Alice', address: { city: 'Tokyo', zip: 200 } }

LodashのcloneDeepメソッドを使うと、すべてのネストされたオブジェクトや配列を含む完全なコピーが作成されます。

まとめ

配列やオブジェクトをコピーする際には、浅いコピーと深いコピーの違いを理解することが重要です。浅いコピーはトップレベルのプロパティのみを複製しますが、深いコピーではすべてのネストされた要素も含めて複製されます。

JavaScriptでは、Object.assignやスプレッド構文を使って浅いコピーを簡単に作成できますが、深いコピーが必要な場合はJSON.stringifyJSON.parse、またはLodashなどのライブラリを使うことが推奨されます。