今回はオブジェクトのコピーについて解説します。オブジェクトのコピーには「浅いコピー」と「深いコピー」の2種類があります。
浅いコピーは、オブジェクトの直接的なプロパティだけをコピーします。ネストされたオブジェクトや配列はコピーされず、元のオブジェクトと同じ参照を持ちます。このため、浅いコピーは短い時間で作成できます。
浅いコピーを作るには、いくつかの方法があります。以下に、代表的な3つの方法を紹介します。
const original = { a: 1, b: { c: 2 } };
const shallowCopy = { ...original };
console.log(shallowCopy); // { a: 1, b: { c: 2 } }
console.log(shallowCopy.b === original.b); // true
const original = { a: 1, b: { c: 2 } };
const shallowCopy = Object.assign({}, original);
console.log(shallowCopy); // { a: 1, b: { c: 2 } }
console.log(shallowCopy.b === original.b); // true
const originalArray = [1, 2, [3, 4]];
const shallowCopyArray = originalArray.slice();
console.log(shallowCopyArray); // [1, 2, [3, 4]]
console.log(shallowCopyArray[2] === originalArray[2]); // true
深いコピーは、オブジェクトのすべてのプロパティを完全にコピーします。ネストされたオブジェクトや配列も新しいものとしてコピーされるため、元のオブジェクトと完全に独立しています。深いコピーは浅いコピーよりも時間がかかりますが、安全なデータ操作が可能です。
深いコピーを作るには、以下の2つの方法が一般的です。
const original = { a: 1, b: { c: 2 } };
const deepCopy = JSON.parse(JSON.stringify(original));
console.log(deepCopy); // { a: 1, b: { c: 2 } }
console.log(deepCopy.b === original.b); // false
この方法は簡単ですが、関数やundefined、特殊なデータ(例えばDateオブジェクトなど)はコピーできないので注意が必要です。
function deepClone(obj) {
if (obj === null || typeof obj !== "object") {
return obj;
}
let clone;
if (Array.isArray(obj)) {
clone = [];
for (let i = 0; i < obj.length; i++) {
clone[i] = deepClone(obj[i]);
}
} else {
clone = {};
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
clone[key] = deepClone(obj[key]);
}
}
}
return clone;
}
const original = { a: 1, b: { c: 2 }, d: [3, 4] };
const deepCopy = deepClone(original);
console.log(deepCopy); // { a: 1, b: { c: 2 }, d: [3, 4] }
console.log(deepCopy.b === original.b); // false
console.log(deepCopy.d === original.d); // false
今回は、JavaScriptのオブジェクトの「浅いコピー」と「深いコピー」について学びました。浅いコピーは簡単ですが、ネストされたオブジェクトや配列がある場合には注意が必要です。深いコピーは時間がかかることがありますが、データの完全な独立を保つことができます。