JavaScript | ES6+ 文法:分割代入 – 関数引数での使用

JavaScript
スポンサーリンク

関数引数での分割代入とは何か

関数のパラメータ部分で分割代入を使うと、渡された配列・オブジェクトから「必要な値だけ」を直接取り出して、引数の宣言に“意図(何を使うのか、欠けたらどうするのか)”を明示できます。ここが重要です:引数そのものが未指定(undefined)のときでも安全に動くよう、外側の既定値(= {} または = [])を必ず付けるのが定石です。

// オブジェクトで受ける(意味ベース)
function connect({ host = "localhost", port = 5432, ssl = false } = {}) {
  return `postgres://${host}:${port}?ssl=${ssl}`;
}
console.log(connect()); // 既定値で安全に動く

// 配列で受ける(位置ベース)
function sum3([a = 0, b = 0, c = 0] = []) {
  return a + b + c;
}
console.log(sum3()); // 0
JavaScript

オブジェクト引数での分割代入(意味で受ける)

既定値をシグネチャに書く

“何が必須で、何が任意か”を引数の宣言で表せます。ここが重要です:undefined にだけ既定値が効く(null は値あり)ことを理解し、必要なら本文内で ?? を使って補正します。

function makeUrl(base, { q = "", page = 1, per = 20, sort = "new" } = {}) {
  const params = new URLSearchParams({ q, page, per, sort });
  return `${base}?${params}`;
}
console.log(makeUrl("/search", { q: "js", per: 5 }));
JavaScript

変数名変更(エイリアス)で語彙を揃える

外部 API のフィールド名を自分のプロジェクトの語彙へ合わせると、可読性が上がります。

function normalizeUser({ user_id: id, display_name: name = "" } = {}) {
  return { id, name: name.trim() };
}
console.log(normalizeUser({ user_id: 7 }));
JavaScript

ネスト引数を安全に受ける

中間オブジェクトが欠けても落ちないよう、外側に {} の既定値を置きます。

function renderCard({ product: { id = 0, name = "" } = {}, price: { jpy = 0 } = {} } = {}) {
  return `<div data-id="${id}"><h2>${name.trim()}</h2><p>価格: ${jpy.toLocaleString("ja-JP")} 円</p></div>`;
}
console.log(renderCard({ product: { id: 1, name: "  Apple  " }, price: { jpy: 123456 } }));
console.log(renderCard()); // 欠けても安全
JavaScript

配列引数での分割代入(位置で受ける)

欠けても動く既定値

配列は“位置”が意味を持ちます。ここが重要です:不足分は undefined になるため、意味のある既定値を付けて防御します。

function toPoint([x = 0, y = 0] = []) {
  return { x, y };
}
console.log(toPoint([5])); // { x: 5, y: 0 }
console.log(toPoint());    // { x: 0, y: 0 }
JavaScript

残余要素(…rest)で“残り全部”をまとめる

先頭だけを主役にし、余りは配列で受け取ると柔軟です。

function handle([event, ...payloads] = []) {
  return `event=${event}, payloads=${payloads.length}`;
}
console.log(handle(["loaded", { id: 1 }, { cache: true }]));
JavaScript

配列×オブジェクトの混在を自然に受ける

位置情報は配列で、意味情報はオブジェクトで受けると読みやすくなります。

function rowView([id = 0, { name = "", price = 0 } = {}] = []) {
  return `${id}:${name.trim()} (${Math.round(price * 1.1)}円)`;
}
console.log(rowView([1, { name: "Apple", price: 100 }]));
JavaScript

実務で効く設計パターン(重要ポイントの深掘り)

外側既定値は“必ず”付ける

未指定の引数に対して分割すると「Cannot destructure property … of undefined」で落ちます。ここが重要です:function f({ ... } = {}) {}function g([ ... ] = []) {} を習慣にする。

function f({ a = 1 } = {}) { return a; }
function g([x = 0] = [])    { return x; }
JavaScript

シグネチャに“軽い整形”、本文に“重い処理”

引数宣言には既定値・別名・trim などの軽い処理まで。重い計算・副作用は本文へ分離し、見通しと性能を保ちます。

function render({ name = "" } = {}) {
  const title = name.trim().toUpperCase(); // 本文で重めの整形
  return `<h1>${title}</h1>`;
}
JavaScript

依存関係と評価順

同じ分割の中では左から右へ評価されます。後続の既定値は前の値を参照できますが、まだ初期化前の変数を参照するとエラー(TDZ)。宣言順を守るか、本文で分割してから使う。

function banner({ title = "Untitled", subtitle = `by ${title}` } = {}) {
  return `<h1>${title}</h1><p>${subtitle}</p>`;
}
console.log(banner({ title: "JS 入門" })); // subtitle に title が反映
JavaScript

null には既定値が効かない

既定値は undefined にのみ発動します。null も既定扱いにしたい場合は、本文で ?? を使って補正します。

function rateText({ rate } = {}) {
  const r = rate ?? 0.1; // null/undefined を 0.1 に
  return `rate=${r}`;
}
console.log(rateText({ rate: null }));
JavaScript

例題で理解を固める

// 1) 検索 API の安全な引数受け取り(意味ベース)
function search(base, { q = "", page = 1, per = 20, sort = "new" } = {}) {
  const params = new URLSearchParams({ q, page, per, sort });
  return `${base}?${params}`;
}
console.log(search("/search"));

// 2) テーブル行レンダリング(混在構造)
function renderRow([id = 0, { name = "", price = 0 } = {}] = []) {
  return `<tr><td>${id}</td><td>${name.trim()}</td><td>${price.toLocaleString("ja-JP")} 円</td></tr>`;
}
console.log(renderRow([2, { name: "  Banana  ", price: 200 }]));

// 3) ユーザー正規化(別名+既定値+軽い整形)
function normalizeUser({ user_id: id, display_name: name = "" } = {}) {
  return { id, name: name.trim() };
}
console.log(normalizeUser({ user_id: 7 }));

// 4) 設定の段階的分割(外側既定値+内側既定値)
function init(cfg = {}) {
  const { ui = {}, api = {} } = cfg;
  const { theme = "light", fontSize = 16 } = ui;
  const { base = "/api", timeout = 3000 } = api;
  return { theme, fontSize, base, timeout };
}
console.log(init()); // 既定値で初期化

// 5) イベント処理(先頭+残余)
function handleEvent([type = "unknown", ...args] = []) {
  return `type=${type} args=${JSON.stringify(args)}`;
}
console.log(handleEvent(["click", { id: 1 }, { x: 10, y: 20 }]));
JavaScript

まとめ

関数引数での分割代入の核心は「必要な値だけを宣言で取り出し、欠けても安全に動く既定値を“引数側”で保証する」ことです。オブジェクトは意味ベース、配列は位置ベースで受け、外側既定値(= {}= [])を必ず付ける。別名で語彙を揃え、軽い整形はシグネチャ、重い処理は本文へ。評価順と TDZ、null への既定値非適用に注意する。これを徹底すれば、初心者でも安全で読みやすい ES6+ の関数設計が自然と身につきます。

タイトルとURLをコピーしました