概要
JavaScriptでは undefined
が多くの不具合の起点になる。
特に入力値、外部APIのレスポンス、オプショナルな設定など、
「値があることを前提に書かれたコード」はしばしば脆弱である。
そこで重要になるのが、**「デフォルト値の戦略的設計」**である。
これは単なる ||
や ??
の話ではなく、フォールバック戦略としての初期値設計、パターンベースの型安全化の話である。
本稿では、デフォルト値設計のパターン、初期化戦略、undefined耐性のある記法と設計判断を解説する。
1. デフォルト値の基本パターン
function greet(name) {
const user = name || 'Guest';
console.log(`Hello, ${user}`);
}
- ✅
||
は「falsy値」にフォールバック →''
,0
,false
も対象になるため注意 - ✅ より明示的には
??
(Nullish Coalescing)を使う
const user = name ?? 'Guest'; // ← null または undefined のみを補完
2. 関数引数のデフォルト値
function createUser(name = 'Anonymous', age = 0) {
return { name, age };
}
- ✅ 呼び出し元で省略された場合の安全な初期化
- ✅
undefined
だけを対象にするため、引数の意図が明確になる
3. オブジェクトの分割代入における初期値
function initConfig({ timeout = 1000, retries = 3 } = {}) {
return { timeout, retries };
}
- ✅ オプショナルなプロパティでも安全に読み取れる
- ✅ 全体が
undefined
の場合にも安全 →{}
をデフォルトとする設計
4. 初期化関数による構造化デフォルト
function getDefaultUser() {
return { name: 'Guest', age: null, loggedIn: false };
}
const user = inputUser ?? getDefaultUser();
- ✅ 複雑なデフォルト構造は関数として切り出す
- ✅ 動的構成・依存性注入を持つ構造にも対応可能
5. フォールバック関数パターン
function getDisplayName(user) {
return user?.name ?? getAnonymousLabel();
}
- ✅
??
に関数を渡すことで、必要なときだけ評価される - ✅ 重い処理の回避 + フォールバックの柔軟性を両立
設計判断フロー
① falsyな値も許容するか? → `??` を使う(`||` は避ける)
② 引数がundefinedの可能性があるか? → デフォルト値で初期化
③ 入力オブジェクトは不完全かもしれないか? → 分割代入 + 初期値設計
④ 複雑な構造の初期値が必要か? → getDefault関数を導入
⑤ フォールバックが動的か? → 関数 + `??` で遅延評価
よくあるミスと対策
❌ ||
によって false
や 0
が意図せず上書きされる
→ ✅ 「null or undefined のみ」を対象にするなら ??
を使う
❌ 関数内で都度 if (!value) value = default
を繰り返す
→ ✅ 関数引数 or 分割代入の初期値に移行
❌ default 値が他モジュールや依存に結合し、テスト困難に
→ ✅ 初期値関数を抽出し、モック差し替え可能な構造へ
結語
デフォルト値の設計は、単なる保険ではない。
それは**“コードの前提条件を明示し、異常系に耐える構造を設計するための防衛的戦略”**である。
-
||
と??
の使い分けは明確に - 関数の引数と分割代入で初期値を設計的に扱う
- 動的なフォールバックは関数化し、依存と責務を切り離す
JavaScriptにおけるデフォルト値設計とは、
“コードの健全性を保証し、入力不備に対して安全な構造を維持するための設計技術である。”