JavaScriptでは、配列やオブジェクトのコピーを行うときに参照コピーが使用されます。
参照コピーはオリジナルの配列やオブジェクトのメモリ位置を新しい変数にコピーするため、どちらか一方を変更するともう一方にも変更が反映されます。
この記事では参照コピーの特性について説明し具体的なケースと関連するメソッドの一覧を紹介します。
参照コピーの特性
上記にも記載した通り参照コピーとはオリジナルのオブジェクトや配列のメモリ位置を新しい変数に割り当てることです。
これにより、新しい変数はオリジナルと同じデータを指すようになります。
そのため、一方の変数を変更すると他方にもその変更が反映されます。
基本的な使用例
let originalArray = [1, 2, 3];
let copiedArray = originalArray;
copiedArray.push(4);
console.log(originalArray); // [1, 2, 3, 4]
console.log(copiedArray); // [1, 2, 3, 4]
この例では、copiedArray
がoriginalArray
の参照をコピーしているため、copiedArray
に要素を追加するとoriginalArray
にもその変更が反映されます。
参照コピーが適用されるケース
参照コピーは、以下のような場合に発生します:
配列のコピー
let array1 = [1, 2, 3];
let array2 = array1;
array2.push(4);
console.log(array1); // [1, 2, 3, 4]
オブジェクトのコピー
let obj1 = { name: "Alice" };
let obj2 = obj1;
obj2.age = 25;
console.log(obj1); // { name: "Alice", age: 25 }
ネストされた構造のコピー
let nestedArray1 = [[1, 2], [3, 4]];
let nestedArray2 = nestedArray1;
nestedArray2[0].push(5);
console.log(nestedArray1); // [[1, 2, 5], [3, 4]]
参照コピーに関わる主なメソッド
参照コピーが影響する主なメソッドには以下のものがあります。
ウェブデザイン技能検定などでは出力のされ方などが出題されたりしますので、是非下記メソッド一覧を参考にいただけたらと思います。
push()
- 配列の末尾に1つ以上の要素を追加します。
let arr = [1, 2, 3];
let arrCopy = arr;
arrCopy.push(4);
console.log(arr); // [1, 2, 3, 4]
pop()
- 配列の末尾から要素を1つ削除します。
let arr = [1, 2, 3];
let arrCopy = arr;
arrCopy.pop();
console.log(arr); // [1, 2]
shift()
- 配列の先頭から要素を1つ削除します。
let arr = [1, 2, 3];
let arrCopy = arr;
arrCopy.shift();
console.log(arr); // [2, 3]
unshift()
- 配列の先頭に1つ以上の要素を追加します。
let arr = [1, 2, 3];
let arrCopy = arr;
arrCopy.unshift(0);
console.log(arr); // [0, 1, 2, 3]
splice()
- 配列の指定した部分を削除または置き換え、新しい要素を追加します。
let arr = [1, 2, 3, 4];
let arrCopy = arr;
arrCopy.splice(1, 2, 5, 6);
console.log(arr); // [1, 5, 6, 4]
reverse()
- 配列の要素の順序を反転させます。
let arr = [1, 2, 3];
let arrCopy = arr;
arrCopy.reverse();
console.log(arr); // [3, 2, 1]
sort()
- 配列の要素を並べ替えます。
let arr = [3, 1, 2];
let arrCopy = arr;
arrCopy.sort();
console.log(arr); // [1, 2, 3]
浅いコピーと深いコピー
参照コピーは「浅いコピー」とも呼ばれます。これは、コピー元とコピー先が同じオブジェクトや配列のメモリ位置を共有するためです。
一方、「深いコピー」は、オリジナルのオブジェクトや配列の完全なコピーを作成し、メモリ位置を共有しません。
深いコピーの例
let originalArray = [1, 2, 3];
let deepCopyArray = JSON.parse(JSON.stringify(originalArray));
deepCopyArray.push(4);
console.log(originalArray); // [1, 2, 3]
console.log(deepCopyArray); // [1, 2, 3, 4]
この方法では、deepCopyArray
はoriginalArray
とは別のメモリ位置を持ち、それぞれ独立して操作できます。
- オリジナルのデータ構造全体を再帰的にコピーし、新しいメモリアドレスを割り当てます。
- 新しい変数はオリジナルとは異なるメモリアドレスを持ちます。
- 変更は独立しており、相互に影響を与えません。
JSON.parse(JSON.stringify())
などライブラリを使用されているケースの場合は出力される内容が異なる場合がありますので、気を付けましょう。
まとめ
参照コピーの特性は、JavaScriptの配列やオブジェクト操作において非常に重要です。
一方の変数を変更するともう一方も変更されことを理解しておくことが重要です。
関連するメソッドとその影響を理解することで、より効果的なプログラミングが可能になります。