TypeScriptの浅いコピーと深いコピー
TypeScriptにおけるコピーの概念
コピー(Copying)
プログラミングにおけるコピーには、大きく2つの方式がある。
- 深いコピー(Deep Copy)
- 浅いコピー(Shallow Copy)
深いコピー(Deep Copy)
- 深いコピーは、コピーした値が変更されても元の値は影響を受けないコピー方式である。
- TypeScriptでは、プリミティブ型である
number、booleanは基本的に深いコピーとして動作する。
let original = 1;
let copied = original;
copied += 2;
console.log(original, copied); // 1 3
元の
originalは変わらず、copiedだけが変更される。
浅いコピー(Shallow Copy)
- 浅いコピーは、コピー先と元の値が同じ参照を共有するコピー方式である。
- TypeScriptでは、**オブジェクト(Object)と配列(Array)**は基本的に浅いコピーとして動作する。
const originalArray = [5, 3, 9, 7];
const shallowCopiedArray = originalArray;
shallowCopiedArray[0] = 0;
console.log(originalArray, shallowCopiedArray);
// [0, 3, 9, 7] [0, 3, 9, 7]
配列
originalArrayがshallowCopiedArrayと同じ参照を共有しているため、一方を変更するともう一方にも影響する。
スプレッド演算子(…)を活用したコピー
- **スプレッド演算子(
...)**を使用すると、1次元配列に限り深いコピーのように使用できる。
const oArray = [1, 2, 3, 4];
const deepCopiedArray = [...oArray];
deepCopiedArray[0] = 0;
console.log(oArray, deepCopiedArray);
// [1, 2, 3, 4] [0, 2, 3, 4]
元の配列はそのまま維持され、コピーだけが変更される。
注意: オブジェクトが入れ子になった配列や入れ子オブジェクトまで完全にコピーするには、スプレッド演算子だけでは深いコピーにならない。
この場合はJSON.parse(JSON.stringify(obj))などを使用する。
まとめ
| 型/方法 | コピー方式 | 特徴 |
|---|---|---|
| number, boolean | 深いコピー | 元とコピーが独立している |
| オブジェクト(Object)、配列(Array) | 浅いコピー | 元とコピーが参照を共有する |
スプレッド演算子... |
1次元の深いコピー | 1次元配列/オブジェクトでは元を保持する |