JavaScript | ES6+ 文法:分割代入 – デフォルト値

JavaScript
スポンサーリンク

デフォルト値(既定値)とは何か

分割代入のデフォルト値は、「取り出そうとした場所に値が無い(undefined)」とき、代わりに使われる“埋め草”です。ここが重要です:デフォルト値は undefined のときだけ発動し、null は「値あり」としてそのまま残ります。配列・オブジェクトどちらでも使え、欠けたデータに強いコードになります。

// 配列
const [a = 0, b = 0] = [1];         // a=1, b=0
const [x = 0] = [undefined];        // x=0(発動)
const [y = 0] = [null];             // y=null(発動しない)

// オブジェクト
const cfg = { theme: undefined, lang: "ja" };
const { theme = "light", lang = "en" } = cfg; // theme="light", lang="ja"
JavaScript

配列の分割代入でのデフォルト値

要素不足を安全に埋める

右側の配列が短いと、足りない位置は undefined になります。ここが重要です:不足を見越して、意味のあるデフォルトを必ず付けておくと安心です。

const toPoint = ([x = 0, y = 0] = []) => ({ x, y });
toPoint([5]);  // { x: 5, y: 0 }
toPoint();     // { x: 0, y: 0 }(外側 [] の既定値が重要)
JavaScript

スキップと併用して必要だけ取る

不要な要素を飛ばしつつ、必要な場所だけ既定値で守ります。

const [first = "N/A", , third = "N/A"] = ["A"]; // first="A", third="N/A"
JavaScript

残余(…rest)と組み合わせる

残りをまとめつつ、先頭だけ既定値で堅くするのが定石です。

const [head = "none", ...tail] = []; // head="none", tail=[]
JavaScript

オブジェクトの分割代入でのデフォルト値

プロパティ欠落に強くなる

存在しないプロパティは undefined。ここが重要です:プロパティごとに既定値を付けて、欠けても安全に動かします。

const opts = { perPage: 20 };
const { q = "", page = 1, perPage = 10 } = opts;
// q="", page=1, perPage=20
JavaScript

名前変更(エイリアス)と併用

外部 API のフィールド名を自分の語彙へ揃えながら既定値を付けると保守性が高まります。

const apiUser = { user_id: 7, display_name: undefined };
const { user_id: id, display_name: name = "" } = apiUser; // id=7, name=""
JavaScript

ネストでの既定値は“外側”が鍵

中間オブジェクト自体が未定義かもしれない場合、外側に {} の既定値を入れて安全に潜っていきます。

const cfg = {};
const { ui: { theme = "light" } = {} } = cfg; // ui が無くても安全
JavaScript

関数パラメータでのデフォルト値(安全設計の要点)

外側の既定値を必ず付ける

引数そのものが未指定のとき、分割代入は undefined を対象にしてしまいエラーになります。ここが重要です:引数の外側に {}[] の既定値を“必ず”付けます。

function connect({ host = "localhost", port = 5432, ssl = false } = {}) {
  return `postgres://${host}:${port}?ssl=${ssl}`;
}
connect(); // 既定値で安全に動く
JavaScript

位置は配列、意味はオブジェクト

配列で“位置どり”、オブジェクトで“意味どり”に分けると、読みやすく拡張しやすいです。

function renderRow([id = 0, name = "", price = 0] = [], { rate = 0.1, round = Math.round } = {}) {
  return `${id}:${name.trim()} (${round(price * (1 + rate))}円)`;
}
JavaScript

評価順・undefined と null・依存関係(重要ポイントの深掘り)

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

同じ分割の中で、後続の既定値は前の値を参照できます(その時点で確定済み)。

const [a = 1, b = a * 2] = []; // a=1, b=2
const { x = 2, y = x + 3 } = {}; // x=2, y=5
JavaScript

既定値が効くのは undefined のみ

null は「値あり」。null も既定にしたいなら、取り出した後で ?? を使います。

const { rate } = { rate: null };
const safeRate = rate ?? 0.1; // null/undefined を 0.1 に補正
JavaScript

TDZ(一時的デッドゾーン)に注意

既定値の式で、まだ初期化前の変数に触れると ReferenceError。宣言順を守るか、依存を外に出します。

// NG
// const { a = b } = {}; let b = 10;
// OK
let b = 10;
const { a = b } = {}; // a=10
JavaScript

実務で効くデフォルト値のパターン

ラベルやフォーマットの“完成品”を分割で受ける

テンプレートは見た目に集中でき、分割で既定の整形を保証できます。

const toYen = n => `${n.toLocaleString("ja-JP")} 円`;
const formatRow = ({ id = 0, name = "", price = 0 } = {}) =>
  `${id}:${name.trim()} (${toYen(price)})`;
JavaScript

安全な設定オブジェクト

必須を最小にし、任意は分割の既定値でカバーします。呼び出し側が省略しても壊れません。

function listProducts(rows, { showInactive = false, rate = 0.1 } = {}) {
  const view = rows
    .filter(r => showInactive ? true : r.active)
    .map(({ id, name = "", price = 0 }) => `${id}:${name.trim()} (${Math.round(price * (1 + rate))}円)`);
  return view.join("\n");
}
JavaScript

“外側既定値+内側既定値”で堅牢に

入れ子の欠落に段階的に備えます。

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

よくある落とし穴と回避策

外側の既定値を忘れてクラッシュ

関数パラメータやネスト分割で、対象が undefined のままだとエラーになります。外側に {}[] を必ず付ける習慣を。

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

オブジェクトを直接整形して読みにくくなる

分割は“取り出しの宣言”。重い処理は補助関数へ分離し、既定値は短くわかりやすく。

// 取り出しは分割、整形は別関数へ
const normalizeUser = ({ id = 0, name = "" } = {}) => ({ id, name: name.trim() });
JavaScript

既定値の副作用

既定値の式は毎回評価されます。重い関数呼び出しを置かない(必要なら外で計算して渡す)。

const heavyDefault = () => slowCompute(); // 既定値に置くのは避ける
JavaScript

例題で理解を固める

// 1) 配列:不足・undefined に強い取り出し
const average = ([a = 0, b = 0, c = 0] = []) => (a + b + c) / 3;
console.log(average([10, 20]));  // 10(= (10+20+0)/3)
console.log(average());          // 0

// 2) オブジェクト:API レスポンスの安全整形
const apiRow = { id: 1, name: undefined, price: 123456 };
const { id = 0, name = "", price = 0 } = apiRow;
console.log(`${id}:${name.trim()} (${Math.round(price * 1.1)}円)`);

// 3) ネスト:中間欠落に備える
const cfg = { ui: { theme: undefined } };
const { ui: { theme = "light", fontSize = 16 } = {} } = cfg;
console.log(theme, fontSize); // "light" 16

// 4) 関数パラメータ:外側既定値+依存の既定値
function banner({ title = "Untitled", subtitle = `by ${title}` } = {}) {
  return `<h1>${title}</h1><p>${subtitle}</p>`;
}
console.log(banner({ title: "JS 入門" })); // subtitle に title が反映

// 5) null は既定値が効かない → ?? で補正
const { rate } = { rate: null };
const r = rate ?? 0.1;
console.log(r); // 0.1
JavaScript

まとめ

分割代入のデフォルト値の核心は「欠けた値(undefined)を、意味のある既定値で安全に埋める」ことです。undefined にだけ発動、null は対象外。配列は位置ベースで不足を埋め、オブジェクトはプロパティ欠落に備え、ネストは外側 {} の既定値が鍵。関数パラメータでは外側既定値を必ず付け、評価順は左から右、重い処理は既定値に置かない。見た目はテンプレートや呼び出し側で、ロジックは補助関数へ分離する——この指針で、初心者でも安全で読みやすい ES6+ の分割代入が使いこなせます。

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