配列やオブジェクトのコピー操作とは?
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.stringify
とJSON.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では、深いコピーを簡単に行うためのライブラリがいくつか存在します。その中でも、Lodash
のcloneDeep
関数が非常に便利です。
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.stringify
とJSON.parse
、またはLodashなどのライブラリを使うことが推奨されます。