スプレッド構文で配列を連結する

生田 陸人
LuaGate エンジニア / 現役エンジニア
編集 LuaGate編集部

このレッスンで分かること

  • スプレッド ... は「中身を取り出して並べる」操作、[...a, ...b] で配列の連結ができます
  • シャローコピーや Math.max(...nums) での引数展開、Set と組み合わせた重複排除にも使える
  • 最小例は function concatArrays(a, b) { return [...a, ...b]; }

スプレッド構文で配列を連結する とは

スプレッド構文 ... で配列を展開し、連結・コピー・引数渡しを簡潔に書く方法を学ぶ。本レッスンでは、スプレッド構文で配列を連結する の基本から実際の使いどころまでを整理し、現場で迷わず使える形に落とし込みます。

スプレッド構文で配列を連結する

配列の連結というと、昔は Array.prototype.concat を使うのが定番でした。今の JavaScript では ... (3 つのドット) を使う スプレッド構文 (spread syntax) の方が直感的で、書く量も読みやすさも勝っています。スプレッドは「配列をばらして並べ直す」操作で、連結・コピー・関数呼び出しの引数展開まで幅広く活躍します。配列を扱う現場で ... は必修記法です。

スプレッド ... は「中身を取り出して並べる」操作。[...arr]arr の要素を 1 つずつ並べた新しい配列を作る。

連結 (concat) の代替

2 つの配列を 1 つにつなぐ書き方は次のとおりです。

JavaScript

const a = [1, 2, 3]; const b = [4, 5, 6]; const c = [...a, ...b]; console.log(c); // [1, 2, 3, 4, 5, 6]

3 つ以上でも同じ要領で並べられます。

JavaScript

const result = [...a, ...b, 99, ...a]; console.log(result); // [1, 2, 3, 4, 5, 6, 99, 1, 2, 3]

concat との違いは「リテラルの中に書ける」点です。[0, ...a, 100] のように、固定値と展開を混ぜて書けます。

JavaScript

// Before const c1 = [0].concat(a).concat([100]); // After const c2 = [0, ...a, 100];

シャローコピーにも使える

const copy = [...arr] と書くだけで配列のシャローコピーが作れます。arr を直接 copy = arr と代入すると参照を共有してしまい、片方を変更するともう片方も変わってしまうので注意です。

JavaScript

const arr = [1, 2, 3]; const copy = [...arr]; copy.push(4); console.log(arr); // [1, 2, 3] console.log(copy); // [1, 2, 3, 4]

スプレッドで作られるのはあくまで シャローコピー。ネストした配列・オブジェクトは参照のままなので注意。

動きを追ってみる

diagram (will load when visible)

評価の流れを箇条書きで言い換えると、次のとおりです。

  • 配列リテラル [ ... ] の中で ...a を見つけたら、a の要素を 1 つずつ展開
  • ...b も同じく要素ごとに展開
  • 固定値 (99 など) はそのまま並ぶ
  • 元配列 a b は変更されず、新しい配列が返る

関数呼び出しの引数展開

スプレッドは関数呼び出しの引数にも使えます。Math.max のように個別引数を取る関数に配列を渡したいときに便利です。

JavaScript

const nums = [3, 7, 2, 9, 4]; console.log(Math.max(...nums)); // 9

従来は Math.max.apply(null, nums) と書いていた処理が、Math.max(...nums) で完了します。

スプレッドと rest の違い

見た目は同じ ... ですが、文脈で意味が逆になります。

  • rest: 関数の引数や分割代入の 左辺 で「残りをまとめる」
  • spread: 配列リテラルや関数呼び出しの 右辺・中 で「中身をばらす」
場面... の意味
関数定義の引数rest (集める)function f(...args)
分割代入の左辺rest (集める)const [x, ...rest] = arr
配列リテラルの中spread (ばらす)[...a, ...b]
関数呼び出しの引数spread (ばらす)Math.max(...nums)

JavaScript

// rest: 引数をまとめる function sum(...nums) { return nums.reduce((a, b) => a + b, 0); } // spread: 配列をばらす const values = [1, 2, 3]; sum(...values); // 6

左辺なら rest、右辺・中なら spread。同じ記号でも対称的な役割を持つ。

よくある間違い

第 1 に、ネストした配列にスプレッドを使うとシャローコピーになります。const copy = [...nested] では、内側の配列は参照を共有します。第 2 に、SetMap などの iterable もスプレッドできますが、オブジェクトはスプレッドの対象が違います (オブジェクトには {...obj} を使う)。第 3 に、...arr 単独では使えません。const x = ...arr は構文エラーです。必ず []f() の中で使います。

Set との組み合わせで重複排除

スプレッドは Set と組み合わせると配列の重複排除に応用できます。Set は重複を許さない iterable なので、new Set(arr) でユニーク化したあと [...] で配列に戻せます。

JavaScript

const arr = [1, 2, 2, 3, 3, 3]; const unique = [...new Set(arr)]; console.log(unique); // [1, 2, 3]

このテクニックは次のレッスンでも登場するので、ぜひ覚えておきましょう。

この章のポイント

ここまでの要点 スプレッド ... は「中身をばらす」操作。連結・コピー・引数展開・重複排除と多用途。左辺の ... は rest (集める)、右辺の ... は spread (ばらす)。シャローコピーであることに注意。

やってみよう

2 つの配列 ab を受け取り、両方を順に並べた新しい配列を返す concatArrays 関数を書きましょう。手順は次のとおりです。

  1. function concatArrays(a, b) { ... } で関数を定義する
  2. return [...a, ...b]; の 1 行で連結
  3. 空配列・通常配列の組み合わせでテストが pass するか確認

ab が空配列でも問題なく動きます。書けたら Math.max(...arr) で配列の最大値を取る練習もしてみると、スプレッドの便利さが体感できます。さらに function fn(...args) (rest) と組み合わせて、可変長関数の中身を別の関数に再展開する書き方も試してみてください。

よくある質問

Q. スプレッド構文の典型的な使い道は?

A. 配列・オブジェクトのコピー([...arr]、{...obj})、結合([...a, ...b])、関数引数の展開(fn(...args))が代表例です。深いコピーはできない点に注意し、ネスト構造を完全複製したいときは structuredClone(obj) を使ってください。

Q. スプレッドとレストの違いは?

A. 見た目は ... で同じですが、配列を展開するのがスプレッド、引数を集めるのがレスト(残余引数)です。function fn(...args) のように関数定義側で使うとレスト、fn(...arr) のように呼び出し側で使うとスプレッドになります。

Q. オブジェクトを展開するときの上書き優先順位は?

A. { ...a, ...b } と書くと b のキーが a を上書きします。デフォルト値を先に展開し、ユーザー設定を後ろで上書きする { ...defaults, ...userOpts } が定番イディオムです。順序を間違えるとデフォルト値が勝ってしまうので注意してください。

次のレッスン

次は スプレッド構文でオブジェクトをマージする で、スプレッド構文 ... で配列を展開し、連結・コピー・引数渡しを簡潔に書く方法を学ぶ を学びます。

事前確認 — 進む前に次の 3 つができることを確認しましょう。

  1. スプレッド配列 の要点を自分の言葉で説明できる
  2. このレッスンの最小コード (または操作手順) を見ずに書ける
  3. 練習問題やクイズで間違えた箇所を読み直して理解した

理解度チェック (30 秒)

Q. スプレッド配列 とは何か、1 文で説明してください。

この章のポイント

A. 本文の「このレッスンで分かること」または冒頭の説明文を見直し、自分の言葉で要約できれば OK。詰まったら本レッスンの最初の H2 セクションを読み返してみましょう。

関連レッスン

要件

  1. スプレッド構文 ... を使って配列を展開すること
  2. 元の配列 ab を破壊しないこと
  3. 両方が空配列のときは空配列を返すこと

入出力例

test-cases.txt

concatArrays([1,2,3], [4,5,6])[1,2,3,4,5,6] concatArrays([1,2], [])[1,2] concatArrays([], [])[] concatArrays(["a","b"], ["c"])["a","b","c"]

ヒント

main.js
main.js
学習モード

メモ

スプレッド構文で配列を連結する

⌘S で保存