スプレッド構文でオブジェクトをコピー・マージ

スプレッド構文(...)を使うと、オブジェクトや配列を簡潔にコピー・マージできます。ES2018 でオブジェクトにも対応し、現在では最もよく使われるコピー方法の一つです。

オブジェクトのコピー

スプレッド構文を使ったオブジェクトのシャローコピーは、非常にシンプルに書けます。

const original = { name: "田中", age: 25 };
const copy = { ...original };

copy.name = "山田";
console.log(original.name); // "田中"(影響なし)

オブジェクトのマージ

複数のオブジェクトを1つにまとめることもできます。同じキーがある場合、後に書いた方の値が優先されます。

const obj1 = { a: 1, b: 2 };
const obj2 = { b: 3, c: 4 };

const merged = { ...obj1, ...obj2 };
console.log(merged); // { a: 1, b: 3, c: 4 }

プロパティの追加・上書き

既存のオブジェクトに新しいプロパティを追加したり、一部を上書きしたりする際に便利です。

const user = { name: "田中", age: 25 };

// プロパティを追加
const withEmail = { ...user, email: "tanaka@example.com" };

// プロパティを上書き
const updated = { ...user, age: 26 };

console.log(withEmail); // { name: "田中", age: 25, email: "tanaka@example.com" }
console.log(updated);   // { name: "田中", age: 26 }

スプレッド構文の位置によって結果が変わります。

{ ...user, age: 26 }

user を展開した後に age を上書きするため、26 になる

{ age: 26, ...user }

先に age: 26 を設定し、その後 user で上書きされるため、25 になる

配列のコピー

配列もスプレッド構文でコピーできます。

const original = [1, 2, 3];
const copy = [...original];

copy.push(4);
console.log(original); // [1, 2, 3](影響なし)

配列のマージ

複数の配列を結合するのも簡単です。

const arr1 = [1, 2];
const arr2 = [3, 4];
const arr3 = [5, 6];

const combined = [...arr1, ...arr2, ...arr3];
console.log(combined); // [1, 2, 3, 4, 5, 6]

途中に要素を挿入することもできます。

const numbers = [1, 5];
const withMiddle = [numbers[0], 2, 3, 4, numbers[1]];
// または
const withMiddle2 = [1, ...[2, 3, 4], 5];

シャローコピーであることに注意

スプレッド構文によるコピーはシャローコピーです。Object.assign() と同様、ネストしたオブジェクトは参照が共有されます。

const original = {
  info: { city: "東京" }
};

const copy = { ...original };
copy.info.city = "大阪";

console.log(original.info.city); // "大阪"(影響を受ける)

ネストしたオブジェクトも含めてコピーするには、structuredClone() を使用するか、手動でネストした部分もスプレッドする必要があります。

// ネストした部分も手動でスプレッド
const deeperCopy = {
  ...original,
  info: { ...original.info }
};

この方法はネストが深くなると煩雑になるため、ディープコピーが必要な場合は structuredClone() の使用をおすすめします。