1. 引数を渡さないと既定値だけが返る
  2. 指定したキーだけが上書きされる
  3. 設定のタグの後ろに追加タグがつながる
  4. 空の設定に追加タグだけを渡したとき
  5. limit に 0 を渡しても 0 のまま残る
コース一覧
モダンJavaScript:データ処理とコード設計
スプレッドとレストで組み替える

モダンJavaScript:データ処理とコード設計

配列の map・filter・reduce・sort、クロージャと高階関数、オブジェクトとクラス、エラー設計、正規表現を学ぶ全 36 レッスン(665 分)のコースです。ローカルの作品データを題材に、表示とデータを分け、絞り込み・並び替え・入力検証までを組み立てます。Promise、fetch、API 通信、モジュールは次のコースで扱います。

1
土台をそろえる
01. このコースで育てるもの15分
02. strict mode が先に教えてくれる間違い15分
03. 表示とデータを切り分ける20分
04. 第1章まとめクイズ10分
2
配列をパイプラインで扱う
01. map で形を変える20分
02. filter と find で絞り込む20分
03. reduce でひとつにまとめる20分
04. sort と比較関数20分
05. 分類してまとめる groupBy20分
06. つなげて組み立てる20分
07. つくる 作品一覧の絞り込みと並び替え30分
08. 第2章まとめクイズ10分
3
関数を道具にする
01. クロージャで状態を閉じ込める20分
02. 設定を覚えた関数をつくる20分
03. 関数を返す関数20分
04. 副作用のない関数20分
05. 第3章まとめクイズ10分
4
オブジェクトを扱いきる
01. 分割代入で必要な値だけ取り出す20分
02. スプレッドとレストで組み替える20分
03. keys と values と entries20分
04. ビット演算でフラグをまとめる20分
05. 第4章まとめクイズ10分
5
クラスで型をつくる
01. クラスとインスタンス20分
02. private フィールドとアクセサ20分
03. 継承と super20分
04. 多態と static20分
05. つくる 作品コレクションをクラスにする30分
06. 第5章まとめクイズ10分
6
エラーを設計する
01. try catch finally20分
02. 自分でエラーを投げる20分
03. 失敗を画面に出す25分
04. 第6章まとめクイズ10分
7
正規表現
01. 正規表現のきほん20分
02. 入力を検証する20分
03. 置換とキャプチャ20分
04. 第7章まとめクイズ10分

スプレッドとレストで組み替える

同じ ... が、広げると集める
解説

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

  • 同じキーがぶつかったら、後ろに書いたほうが残ります
  • ... は置いた場所で、ばらまくか、まとめるかが変わります

使わない引数まで書かされる

呼び出すたびに変わるかもしれない値が増えてくると、引数を 1 つずつ足す設計が破綻します。

JavaScript

applyTheme("light", 16, 3, false);

変えたいのが 3 番目だけでも、前の 2 つを書かされます。しかも false が何を意味するのか、呼び出し行を見ても分かりません。設定はオブジェクト 1 つで受け取り、足りないところを既定値で埋める形にします。

JavaScript

function applyTheme(custom = {}) { const base = { theme: "light", fontSize: 16, columns: 2 }; return { ...base, ...custom }; } console.log(applyTheme({ columns: 3 })); // { theme: "light", fontSize: 16, columns: 3 }

{ ...base, ...custom } は「base の中身をばらまき、その上に custom の中身をばらまく」という意味です。同じキーがぶつかったときは後に書いたほうが残ります。だから既定値を先、受け取った設定を後ろに置きます。

解説

順番を逆にすると、いつでも既定値が勝つコードになります。指定したはずの設定が効かないという形で表面化するので、原因の特定に時間がかかります。既定値は先、と型で覚えてください。

|| で埋めると 0 が消える

既定値を埋めるだけなら custom.columns || 2 でもよさそうに見えます。ここに落とし穴があります。

書きかた0 を渡すnull を渡すキーを渡さない
{ ...base, ...custom }0null既定値
custom.columns || 2222
custom.columns ?? 2022

利用者が「0 でよい」と指定した意図を、|| は消してしまいます。空文字や false でも同じことが起きます。ばらまいて重ねるやりかたは値の真偽を見ないので、0 も false もそのまま採用されます。

ひとつ注意があります。重ねるやりかたはキーさえあれば、値が undefined でも上書きします。{ columns: undefined } を渡すと既定値は消えて undefined になります。呼び出し側で「指定しない」を表したいなら、そのキーを渡さないのが正解です。

残りをまとめる ...

... を値を作る側に書くとばらまき、受け取る側に書くとまとめるという逆向きの働きになります。後者をレストと呼びます。

JavaScript

function joinLabels(separator, ...items) { return items.join(separator); } console.log(joinLabels(" / ", "HTML", "CSS")); // HTML / CSS console.log(joinLabels(" / ")); // 空文字

...items は「残りの引数を全部この配列に入れる」という指示です。1 つも渡されなければ空の配列になるので、undefined かどうかを調べなくても length や map をそのまま呼べます。決まりは 2 つで、必ず最後の引数であることと、1 つしか置けないことです。残りをまとめる、という意味を考えれば当然の制限です。

呼び出す側で配列をばらして渡したいときも ... を書きます。

JavaScript

const chosen = ["HTML", "CSS"]; console.log(joinLabels(" / ", ...chosen)); // HTML / CSS console.log(joinLabels(" / ", chosen)); // HTML,CSS 配列 1 つとして渡っている

下の行は items が [["HTML", "CSS"]] になっています。入れ子が 1 段深いことに気付かないと、結合の結果がおかしいという形で表面化します。

よくある間違い

  • 既定値を後ろに置く — { ...custom, ...base } と書くと、指定した設定が既定値で上書きされて消えます
  • レスト引数を前に置く — function ng(...items, custom) {} は構文エラーです。残りをまとめる以上、後ろに何かを置くことはできません
  • 浅いコピーのまま中身を書き換える — 重ねて作ったオブジェクトの中の配列は、元の配列と同じものを指しています。push すると元まで増えるので、新しい配列を作って差し替えます

要件

  1. 関数名は buildViewOptions。第1引数は設定オブジェクトで省略可能、第2引数以降はレストで追加タグを受け取る
  2. 既定値は { sort: "year", order: "desc", limit: 5, tags: [] } とし、受け取った設定で上書きする
  3. tags は合成後のタグ配列の後ろに、レストで受け取った追加タグをつないだ新しい配列にする
  4. 戻り値は sort, order, limit, tags を持つ新しいオブジェクト。limit に 0 を渡したときは 0 のままにする

入出力例

buildViewOptions() → {"limit":5,"order":"desc","sort":"year","tags":[]} buildViewOptions({"order":"asc"}) → {"limit":5,"order":"asc","sort":"year","tags":[]} buildViewOptions({"sort":"views","tags":["HTML"]}, "CSS", "JavaScript") → {"limit":5,"order":"desc","sort":"views","tags":["HTML","CSS","JavaScript"]} buildViewOptions({}, "HTML") → {"limit":5,"order":"desc","sort":"year","tags":["HTML"]} buildViewOptions({"limit":0}) → {"limit":0,"order":"desc","sort":"year","tags":[]}

ヒント

既定値を先、受け取った設定を後ろに置いて合成します。順番を逆にすると既定値がいつでも勝ちます。

追加タグは function buildViewOptions(options = {}, ...extraTags) の形で受け取れます。1 つも渡されなければ空配列です。

合成したあとに tags だけを差し替えます。merged.tags を push で伸ばすと既定値の配列まで変わってしまいます。

生田 陸人
監修生田 陸人
ゆめさくエンジニア / 現役ソフトウェアエンジニア監修者プロフィールを見る →
編集 ゆめさく編集部·公開 2026/03/27·更新 2026/08/26

関連レッスン

  • keys と values と entries

    オブジェクトを配列に変えて、map や filter や reduce を使えるようにする 3 つの関数です。fromEntries でオブジェクトに戻せます。

  • ビット演算でフラグをまとめる

    公開・注目・新着のような独立した設定を 1 つの数値で持ち、立てる・降ろす・切り替える・調べるを演算子で行います。

  • 第4章まとめクイズ

    分割代入の既定値、スプレッドの上書き順、レスト引数、entries と fromEntries、ビットフラグの操作をコードを読んで確かめます。

  • クラスとインスタンス

    class で作品の設計図を書き、new で作ったインスタンスにデータと処理をまとめます。素のオブジェクトの配列を map でインスタンスの配列に変える形まで進みます。

このレッスンに出てくる用語

意味があいまいなまま進んだ語は、ここから読み直せます。

  • 引数位置引数=順番で渡す。
  • 設計何をどう作るかを決める前工程
  • オブジェクトキーと値のペアで構造を作るデータ
  • 配列サイズ固定の同型データの集まり
  • 関数処理に名前を付けて再利用できる単位
  • 戻り値呼び出し元への返答を表す点線矢印
main.js
学習モード
エディタを読み込んでいます

メモ

スプレッドとレストで組み替える

⌘S で保存