オプショナルチェーンとは何か
オプショナルチェーン(?.)は「途中のオブジェクトや配列が null/undefined でも、エラーにせず安全に次へ進む(または止まる)」ための記法です。ここが重要です:?. は null/undefined のときだけ短絡して undefined を返します。0、””、false は“有効な値”としてそのまま通過します。
const zip = order?.customer?.address?.zip; // 中間が無ければ undefined、TypeErrorにならない
JavaScript基本の使い方(プロパティ・配列・関数呼び出し)
プロパティアクセスで使う(ドット)
const city = order?.customer?.address?.city;
JavaScript途中の customer や address が無ければ undefined を返します。存在すれば最後の city を取得します。
配列インデックスに使う(ブラケット)
const firstSku = order?.items?.[0]?.sku;
JavaScriptitems が無い、0番目が無い、sku が無い、のどれでも安全に undefined になります。
関数・メソッド呼び出しに使う(?.())
const result = maybeFn?.(123); // 関数があれば呼ぶ、無ければ undefined
const ok = user.formatName?.().toUpperCase?.(); // 段階的に安全に呼び出す
JavaScriptここが重要です:呼び出し対象が undefined/null のときは“呼ばない”。副作用・例外を防げます。
既定値との組み合わせ(?? と併用して堅牢に)
欠損なら既定値を与える(null合体)
const theme = settings?.prefs?.theme ?? "light";
JavaScript?. が undefined に短絡したら、その場で “light” を採用します。0・””・false を“有効値”として尊重したい場面は ?? を使うのが鉄則です。
|| と ?? の違い(ここが重要)
- || は falsy(0、””、false、NaN、null、undefined)で既定値に切り替える
- ?? は null/undefined のときだけ既定値に切り替える
const page = input?.page ?? 1; // 0 を尊重して 0 のまま
const q = input?.q || "all"; // 空文字を未指定扱いで "all"
JavaScript使えない場所・制約(落とし穴の回避)
代入の左側には使えない
// NG: obj?.user = { ... } // 代入の左辺に ?. は書けない(構文エラー)
const next = { ...obj, user: { ...(obj.user ?? {}), name: "Alice" } }; // 非破壊で安全に
JavaScript更新したいときは“非破壊更新(スプレッド)”に切り替えます。
分割代入のパターン内には使えない
// NG: const { a: { b }?. } = obj
// OK(受け皿に {} を置く)
const { a: { b = 0 } = {} } = obj;
JavaScript分割代入では中間に {} の既定値を置いて欠損を吸収します。
in や算術・比較の中での誤用に注意
"key" in obj?.child のような書き方はできません。ガードしてから判定します。
const child = obj?.child;
const has = child != null && ("key" in child);
JavaScript反復・探索での実践パターン
ネストを辿って安全に取得
function getPath(obj, path) {
let cur = obj;
for (const k of path) {
cur = Array.isArray(cur) ? cur?.[k] : cur?.[k];
if (cur === undefined) break;
}
return cur;
}
getPath(order, ["customer", "address", "zip"]) ?? "(unknown)";
JavaScript可読性の高いガード付き処理
const items = order?.items ?? [];
for (const it of items) {
// items が無ければ空配列で回す
}
JavaScriptここが重要です:入り口で “?? []” を与えると後続がシンプルになります。null/undefined ガードが一箇所に集約され、読みやすさが上がります。
&& との違い(置き換えの指針)
?. は null/undefined だけで止まる
// && は 0 や "" でも止まる(意図せず止まりがち)
const next1 = input && input.page && (input.page + 1); // 0 で止まる
// ?. は 0 や "" を通す(期待どおり)
const next2 = (input?.page ?? 0) + 1;
JavaScriptここが重要です:0・””・false を“有効値”として扱う仕様なら ?.+?? を選ぶ。古い環境や簡易停止だけが欲しい場面では && も有効です。
delete・存在判定・例外回避の周辺知識
delete と併用(存在しないなら何もしない)
delete obj?.temp; // obj が null/undefined なら true を返し何もしない
JavaScript存在判定は hasOwn/in を使い分ける
?. は“安全なアクセス”であり、キーの有無の判定器ではありません。判定は以下の通り。
Object.hasOwn(obj ?? {}, "key"); // 自前のキーだけ
"key" in (obj ?? {}); // 継承も含む
JavaScript外部入力に対して
外から来たデータは null/undefined が混ざりやすい。?. と ?? を組み合わせ、必要ならスキーマ検証(型チェック)を併用します。
実践レシピ(すぐ使える定番)
文言取得の安全化
const title = msgs?.title?.ja ?? "Welcome";
JavaScriptAPIレスポンスの整形
function toPublicUser(u) {
return {
id: u?.id ?? -1,
name: u?.profile?.name ?? "(unknown)",
email: u?.contacts?.email ?? null
};
}
JavaScriptネスト配列の安全なアクセス
const sku = order?.items?.[findIndex]?.sku ?? "(none)";
JavaScriptまとめ
オプショナルチェーンは「中間が null/undefined でも安全に辿る」ための最短の書き方です。0・””・false を“有効値”として通す点が最大の利点で、既定値は ?? と組み合わせるのが定石。代入の左辺・分割代入パターン内には使えないため、更新は非破壊(スプレッド)に切り替える。存在判定は hasOwn/in を使い分け、反復では入り口で ?? によるガードを与える。これらを押さえれば、初心者でもネスト構造に対して短く、堅牢で、意図どおりのアクセスが書けます。
