高校倫理1433840 views
LaTeX957673 views
中学英語809046 views
中学理科1626729 views
世界の国560930 views
英語608453 views
MathPython492025 views
高校国語785873 views
小学社会308762 views
りんご194232 views
Help
Tools

English

TypeScript における配列のコピー(浅いコピーと深いコピー)

TypeScript で配列をコピーするとき、浅いコピー(shallow copy)と深いコピー(deep copy)の違いを理解しておく必要がある。

浅いコピー

浅いコピーは配列の第一階層だけを複製する。プリミティブ値の配列であれば問題ないが、オブジェクトや配列を要素に持つ場合は参照が共有される。

const original = [1, 2, 3];

// スプレッド構文
const copy1 = [...original];

// Array.from
const copy2 = Array.from(original);

// slice
const copy3 = original.slice();

スプレッド構文が最も簡潔で、現代の TypeScript では標準的な書き方である。Array.from は配列風オブジェクト(NodeList など)を配列に変換する用途でも使える。slice は引数なしで呼ぶと全要素のコピーを返す。

ネストした配列の問題

浅いコピーでは内部のオブジェクトや配列は同じ参照を指す。

const nested = [[1, 2], [3, 4]];
const shallowCopy = [...nested];

shallowCopy[0][0] = 100;
console.log(nested[0][0]); // 100(元の配列も変わる)

内部配列 [1, 2] への参照がコピー先と共有されているため、片方を変更するともう片方にも影響する。

深いコピー

深いコピーはネストしたすべての階層を再帰的に複製する。

const nested = [[1, 2], [3, 4]];

// structuredClone(モダンな方法)
const deepCopy = structuredClone(nested);

deepCopy[0][0] = 100;
console.log(nested[0][0]); // 1(元の配列は変わらない)

structuredClone は ES2022 以降のランタイムで利用でき、循環参照も正しく処理する。ただし関数や Symbol、DOM ノードなど一部の値はコピーできない。

古い環境や structuredClone が使えない場合は JSON.parse(JSON.stringify(obj)) という方法もあるが、undefined や関数、Date オブジェクトなどが正しく扱われない点に注意が必要である。

型付き配列のコピー

TypeScript では型情報がコピー先にも引き継がれる。

type User = { name: string; age: number };

const users: User[] = [
  { name: "Alice", age: 30 },
  { name: "Bob", age: 25 },
];

const usersCopy: User[] = structuredClone(users);

コピー後の配列も User[] 型として扱われ、型安全性が維持される。