Nullish coalescing とは何か(まずイメージから)
Nullish coalescing(ヌリッシュ・コアレスシング)は?? という演算子で書く、
「値が null または undefined のときだけ、代わりの値を使う」ための仕組みです。
一番シンプルな例はこれです。
const input = undefined;
const value = input ?? "デフォルト";
console.log(value); // "デフォルト"
JavaScriptinput が null か undefined なら、「右側の "デフォルト" を使う」という意味になります。
逆に、0 や "" や false のような「値としては存在しているもの」は、そのまま使います。
ここが重要です。
「“値がない” 本当の意味での “空”(null / undefined)のときだけデフォルトを使いたい」
という場面では、?? がベストです。
|| と ?? は何が違うのか(ここをしっかり)
従来よく使われていた || の問題点
ES2020 以前は、「デフォルト値」を書くのに || をよく使っていました。
const input = 0;
const value = input || 10;
console.log(value); // 10
JavaScriptここで問題なのは、input が 0 でも、"" でも、false でも、
「全部ダメな値」とみなされて右側が使われてしまうことです。
|| は「左が falsy(偽っぽい値)」なら、右を使う、というルールだからです。
falsy に含まれるのは、0, "", false, null, undefined, NaN などです。
?? は「null / undefined だけ」を特別扱いする
?? はルールがはっきりしています。
左側が null または undefined のときだけ、右側を使う。
それ以外の値(0, “”, false など)は、ちゃんと「ある値」として扱う。
例えば次のコードを見てください。
console.log(0 || 10); // 10
console.log(0 ?? 10); // 0
console.log("" || "空文字"); // "空文字"
console.log("" ?? "空文字"); // ""
console.log(false || true); // true
console.log(false ?? true); // false
console.log(null || "N"); // "N"
console.log(null ?? "N"); // "N"
console.log(undefined || "U"); // "U"
console.log(undefined ?? "U"); // "U"
JavaScript「0 や空文字は有効な値として認めたい。
本当に “ない” とき(null / undefined)だけデフォルトにしたい。」
という場面では、?? を選ぶべきだと分かるはずです。
ここが重要です。|| は「偽っぽい値なら全部ダメ」、?? は「本当に不在(null / undefined)だけ特別扱い」。
この違いを理解すると、どこでどちらを使うかの判断が一気に楽になります。
基本形:左 ?? 右 の読み方と典型パターン
基本の読み方
a ?? b は、「a が null / undefined なら b、それ以外なら a」という意味です。
const a = null;
const b = a ?? "デフォルト";
console.log(b); // "デフォルト"
JavaScriptもう少しパターンを変えてみます。
console.log(undefined ?? "X"); // "X"
console.log(null ?? "X"); // "X"
console.log(0 ?? 10); // 0
console.log("" ?? "EMPTY"); // ""
console.log(false ?? true); // false
JavaScript「0 や false も尊重したい」というときに ?? は非常に強力です。
設定値・オプションのデフォルトと相性が良い
例えば、設定オブジェクトからリトライ回数を読み出すコードを考えます。
const config = { retries: 0 };
// `||` で書くと…
const count1 = config.retries || 3; // 0 が「ダメ」とみなされて 3 になる
// `??` で書くと…
const count2 = config.retries ?? 3; // 0 は有効な値としてそのまま使う
console.log(count1); // 3
console.log(count2); // 0
JavaScriptここで「0 回リトライ」という設定もアリなら、?? の方が正しいです。|| を使うと、0 や “” が無条件に「不正な値」の扱いになってしまいます。
Optional chaining との組み合わせ(超よく使うパターン)
?. + ?? で「安全アクセス+デフォルト」
API レスポンスなどで、深いプロパティに安全にアクセスしつつ、
なかったときにはデフォルトを使いたい、という場面はとても多いです。
そんなときは Optional chaining(?.)と ?? を合わせて使います。
例を見てみます。
const user = {
profile: {
name: "Alice",
address: {
city: "Tokyo",
},
},
};
// address がないかもしれない
const city = user.profile?.address?.city ?? "不明";
console.log(city); // "Tokyo"
JavaScriptuser.profile?.address?.city 部分は
どこかで null / undefined に出会ったらそこで止まり、全体が undefined になります。
そのあと ?? "不明" で、「なかったら不明」と補っているわけです。
profile がない、address がない、city がない、どの場合も安全に「不明」になります。
ここが重要です。
「あるか分からない深いプロパティ」には ?.、
「なかったときの埋め草」には ??。
このコンビは、実務で頻出する「防御的なコード」を非常に短く、読みやすくしてくれます。
実際のコードでの使いどころを具体的に見る
例1:ユーザーのニックネームがなければ本名、それもなければ “名無し”
const user = {
// nickname: "Alice-chan",
name: "Alice",
};
const nickname = user.nickname ?? user.name ?? "名無し";
console.log(nickname); // "Alice"
JavaScriptuser.nickname が null / undefined なら user.name を見て、
それもなければ "名無し" になります。
同じことを || で書くと、「空文字のニックネーム」や「空文字の名前」も潰してしまう可能性があります。
例2:設定オブジェクトから安全に値を読む
const defaultConfig = {
theme: "light",
pageSize: 10,
};
function buildConfig(userConfig) {
return {
theme: userConfig.theme ?? defaultConfig.theme,
pageSize: userConfig.pageSize ?? defaultConfig.pageSize,
};
}
console.log(buildConfig({ theme: "dark" })); // { theme: "dark", pageSize: 10 }
console.log(buildConfig({ pageSize: 0 })); // { theme: "light", pageSize: 0 }
console.log(buildConfig({ pageSize: undefined })); // { theme: "light", pageSize: 10 }
JavaScriptここでは、pageSize: 0 は「有効な値」として扱いたいので、そのまま残します。
もし || を使っていたら、0 が「ダメ」とされて 10 に置き換えられてしまいます。
例3:フォームの入力値を扱う
const form = {
age: "", // ユーザーが空のまま送信した
height: "0", // 0 と入力した
};
const age = form.age ?? "未入力";
const height = form.height ?? "未入力";
console.log(age); // ""(空文字として扱う。判定は別でやる)
console.log(height); // "0"
JavaScriptここで || を使うと、
空文字 "" や "0" の扱いが変になりがちです。
?? を使うことで、「入力が全く来ていない(null/undefined)」と
「ユーザーが空文字や 0 を入れてきた」を、きちんと区別できます。
注意点と書き方のコツ
?? は優先順位に注意(カッコで明示する)
?? と ||、&& などを混在させるときは、
優先順位のルールがややこしくなるので、カッコを使って意図をはっきりさせましょう。
例えばこうです。
const a = null;
const b = 0;
// 良くない(読み手が悩む)
const value1 = a ?? b || 10;
// 意図をカッコで示す
const value2 = (a ?? b) || 10;
const value3 = a ?? (b || 10);
JavaScript自分の頭の中で思っている順番を、カッコでそのまま表現してしまうのが安全です。
「null / undefined だけが “不在”」という前提を忘れない
?? は「null と undefined だけを不在扱いする」演算子です。
つまり、「0 や空文字も不在扱いしたい」という要件なら、?? は向きません。
その場合は、ちゃんと自分で条件を書くか、用途に応じて || を使うことも選択肢になります。
ここが重要です。
「どこまでを “ないもの” と見なすか」は、仕様の一部です。?? を使うときは、「本当に null / undefined だけを特別扱いしたいか?」を一度自分に問い返してください。
まとめ
Nullish coalescing 演算子 ?? の本質は、
「本当に値が存在しないとき(null / undefined)だけ、デフォルト値にフォールバックする」ことです。
押さえておきたいポイントは次の通りです。
a ?? b は「a が null / undefined なら b、それ以外なら a」|| は「0, “”, false も含めた falsy を全部ダメ扱いする」が、?? は null / undefined だけを不在扱いする
設定値、ユーザー入力、API レスポンスなどで「0 や空文字も正当な値」として扱いたいときに特に有効
Optional chaining(?.)と組み合わせると、「安全アクセス+デフォルト値」をとても短く書ける
何でもかんでも ?? ではなく、「本当に null / undefined だけに反応させたいのか?」を意識して使う
まずは、自分のコードの中で「|| でデフォルト値を入れているところ」を一つ見つけて、
そこを ?? に変えてみてください。
「0 や空文字の扱い」がどう変わるかを体感すると、?? を使うべき場面と、|| を使うべき場面が、かなりクリアに見えてきます。
