JSの「…」スプレッド構文

配列

const foo = [1, 2];

// 配列のクローン
const bar = [...foo]; // => [1, 2]

// 要素を追加して新しい配列を生成
const baz = [...foo, 3, 4]; // => [1, 2, 3, 4]

// 配列をマージ
const hoge = [...foo, ...bar]; // => [1, 2, 1, 2]

オブジェクト

const foo = { a: 1, b: 2 };

// オブジェクトのクローン
const bar = { ...foo }; // => { a: 1, b: 2 }

// プロパティを追加した新しいオブジェクトの生成
const baz = { ...foo, c: 3 }; // => { a: 1, b: 2, c: 3 }

// オブジェクトのマージ
const hoge = { ...foo, ...{ c: 3, d: 4 } }; // => { a: 1, b: 2, c: 3, d: 4 }

// 元のオブジェクトに同名プロパティがある場合は置き換わる
const fuga = { ...foo, b: 3 }; // => { a: 1, b: 3 }
const piyo = { ...foo, ...{ a: 3, b: 4 } }; // => { a: 3, b: 4 }

注意点 スプレッド構文はシャドーコピーらしい

const foo = {
  a: {
    b: 1
  }
};

const bar = { ...foo };
foo.a.b = 2;
console.log(bar); // => { a: { b: 2 } }

情報源: JSのスプレッド構文を理解する – Qiita