JavaScript | ES6+ 文法:関数の進化 – パラメータ分解

JavaScript
スポンサーリンク

パラメータ分解(分割代入)とは何か

パラメータ分解は、関数の引数に「オブジェクトや配列をその場で分解して、必要な部分だけ取り出す」ES6の構文です。ここが重要です:関数シグネチャ(引数の書き方)に“必要なフィールド・既定値・名前の意図”を直接表現できるため、未指定や欠落に強く、読みやすい関数を作れます。

// オブジェクトの分解
function formatUser({ id, name }) {
  return `${id}:${name.trim()}`;
}

// 配列の分解
function toPoint([x, y]) {
  return { x, y };
}
JavaScript

オブジェクトのパラメータ分解(既定値と外側の {} が鍵)

欠けても安全にする既定値

各フィールドに既定値を付けることで、引数オブジェクトにそのプロパティが無くても安全に動きます。ここが重要です:引数そのものが未指定のときに備えて、外側に {} の既定値を必ず付けます。

function makeUrl(
  base,
  { q = "", page = 1, per = 20, sort = "new" } = {} // 外側の {} が必須
) {
  const params = new URLSearchParams({ q, page, per, sort });
  return `${base}?${params.toString()}`;
}

makeUrl("/search");                         // /search?q=&page=1&per=20&sort=new
makeUrl("/search", { q: "js", per: 5 });    // 欠けた分は既定値で補完
JavaScript

名前変更(エイリアス)と既定値の併用

APIのプロパティ名を“使いやすい名前”に変えたい場合は、分解で名前変更しつつ既定値を与えます。

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

ネストの段階的分解(読みやすさ優先)

深いオブジェクトは“必要な階層だけ”段階的に分解します。ここが重要です:一気に1行でネストを解体すると読みにくいので、段階を踏むのがコツです。

function init(cfg = {}) {
  const { ui = {}, api = {} } = cfg;
  const { theme = "light" } = ui;
  const { base = "/api", timeout = 5000 } = api;
  return { theme, base, timeout };
}
JavaScript

配列のパラメータ分解(位置ベースで安全に)

不足分を既定値で埋める

配列は要素の“位置”で受け取り、足りないところは既定値で埋めます。ここが重要です:引数そのものが未指定に備えて、外側に [] の既定値を付けます。

function toPoint([x = 0, y = 0] = []) {
  return { x, y };
}

toPoint([5]); // { x: 5, y: 0 }
toPoint();    // { x: 0, y: 0 }
JavaScript

先頭だけ固定、残りは柔軟(残余引数との併用)

先頭要素だけ取り、残りはまとめて受けたいときは残余引数を使います。

function logFirst([first, ...rest] = []) {
  console.log("first:", first);
  console.log("others:", rest);
}
JavaScript

評価のルール(undefined・null・順序・TDZ)

既定値が効くのは“未指定/undefined”だけ

ここが重要です:既定値は未指定か undefined のときに発動します。null は「値あり」とみなされて既定値になりません。

function nOr(n = 0) { return n; }
nOr();           // 0(未指定 → 既定値)
nOr(undefined);  // 0(undefined → 既定値)
nOr(null);       // null(既定値は発動しない)
JavaScript

左から右へ順に評価される

後続の既定値が前の引数に依存するなら、その時点で前の値は確定済みです。

function total(price, rate = 0.1, add = p => p * rate) {
  return Math.round(price + add(price));
}
JavaScript

宣言前参照(TDZ)に注意

既定値の式で、まだ初期化されていない外部変数に触れると ReferenceError。宣言順を守ること。

// NG(y は宣言前 → TDZ)
// function f(x = y) { return x; }
// let y = 5;
JavaScript

実務パターン(“壊れにくい”インターフェース設計)

設定オブジェクトを堅牢にする

必須・任意を分解で明示して、欠けても動く既定値を付けます。ここが重要です:関数の契約(受け取る形)がコードに現れ、誤用が減ります。

function connect({ host = "localhost", port = 5432, ssl = false } = {}) {
  return `postgres://${host}:${port}?ssl=${ssl}`;
}
JavaScript

コールバック+追加設定の分離

要素をコールバックで処理し、追加設定は別の引数(オブジェクト)で受けると読みやすく拡張しやすいです。

function transform(rows, mapFn, { rate = 0.1, round = Math.round } = {}) {
  return rows.map(r => mapFn({ id: r.id, priceWithTax: round(r.price * (1 + rate)) }));
}
JavaScript

よくある落とし穴と対策(重要ポイントの深掘り)

外側の {}/[] を忘れてクラッシュ

分解だけ書いて外側既定値を付けないと、未指定時に “Cannot destructure property … of undefined” などで落ちます。必ず外側に {}[] を付ける。

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

ネストを“1行でやり過ぎる”

深い分解は段階的に。保守や差分の追跡が容易になります。

null を未指定と誤解しない

null は既定値になりません。null 許容のときは関数内で補正します(?? が便利)。

function safeRate(rate) { return rate ?? 0.1; } // null/undefined を 0.1 に
JavaScript

例題で理解を固める

// 1) URL 生成:分解+既定値で欠けても安全
function buildUrl(base, { q = "", page = 1, per = 20, sort = "new" } = {}) {
  const params = new URLSearchParams({ q, page, per, sort });
  return `${base}?${params}`;
}
buildUrl("/search");                         // 既定値で生成
buildUrl("/search", { q: "js", per: 5 });    // 欠けた分は既定

// 2) ユーザー整形:名前変更+既定値
function shapeUser({ user_id: id, display_name: name = "" } = {}) {
  return { id, name: name.trim() };
}

// 3) 配列引数:不足分を既定値で埋める
function sumFirstTwo([a = 0, b = 0] = []) { return a + b; }
sumFirstTwo([2]);     // 2
sumFirstTwo();        // 0
JavaScript

まとめ

パラメータ分解の核心は「引数の“形”を関数シグネチャで明示し、未指定や欠落に強い設計にできる」ことです。オブジェクト分解では外側 {} を必ず付け、フィールドに妥当な既定値を与える。配列分解は位置ベースで不足分を既定値で埋める。評価は左から右、既定値が効くのは未指定/undefined、宣言順(TDZ)に注意。これらを徹底すれば、初心者でも“壊れにくく読みやすい”ES6+ の関数インターフェースを自信をもって設計できます。

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