Spread/Rest: 展開と収集
... の二つの顔。配列/オブジェクト操作の必須構文。
Spread
... で配列/オブジェクトを展開。
Rest
... で残りをまとめる。
浅いコピー
ネストしたオブジェクトは参照のまま。
Spread/Rest とは?
同じ `...` という記号を使いますが、文脈によって意味が逆になります。関数呼び出しや配列リテラルの中では「展開(Spread)」、関数の引数定義や分割代入の左辺では「集約(Rest)」として機能します。
// 配列の展開const arr1 = [1, 2, 3];const arr2 = [...arr1, 4, 5]; // [1, 2, 3, 4, 5]
// オブジェクトの展開const obj1 = { a: 1, b: 2 };const obj2 = { ...obj1, c: 3 }; // { a: 1, b: 2, c: 3 }
// 関数呼び出しで展開Math.max(...arr1); // 3
// Rest パラメータfunction sum(...nums: number[]) { return nums.reduce((a, b) => a + b, 0);}sum(1, 2, 3, 4); // 10Bad
// ❌ Bad: apply で配列を渡すMath.max.apply(null, [1, 2, 3]);
// ❌ concat で結合var merged = arr1.concat(arr2);Good
// ✅ Good: スプレッド構文Math.max(...[1, 2, 3]);
// ✅ スプレッドで結合const merged = [...arr1, ...arr2];パターン
// 浅いコピーconst copy = [...original];const objCopy = { ...original };
// 配列の途中に挿入const withInsert = [...arr.slice(0, 2), 'new', ...arr.slice(2)];
// デフォルト値とマージconst config = { ...defaults, ...userConfig };
// 分割代入との組み合わせconst [first, ...rest] = [1, 2, 3, 4];// first = 1, rest = [2, 3, 4]
const { a, ...others } = { a: 1, b: 2, c: 3 };// a = 1, others = { b: 2, c: 3 } Tip: スプレッドは浅いコピー。ネストしたオブジェクトには注意。
合格ライン
Spread と Rest の違いを説明できる
オブジェクトのマージができる
演習課題
課題1: Spread
スプレッド構文で配列をマージしてください。
課題2: Rest
Rest パラメータで可変長引数を受け取ってください。