JavaScriptで値の初期設定をするとき、`||` は `0` や空文字 `""` まで「値がない」と扱います。null・undefinedだけを置き換えたいなら `??` が適しています。実行結果を見て選び方を確認しましょう。
??と||の違いは「置き換える条件」
`a || b` は左の `a` が falsy(真偽判定で false と扱われる値)のときに `b` を返します。`a ?? b` は `a` が `null` または `undefined` のときだけ `b` を返します。どちらも、左側で結果が決まれば右側を評価しない短絡評価です。
用語解説:falsy(フォルシー)
JavaScriptで条件判定時に false と扱われる値。例えば 0、空文字、false、null、undefined、NaN など。データとして無効と同じ意味ではありません。
用語解説:null / undefined
null は「値がない」ことを明示する値、undefined は代入されていない変数や存在しないプロパティなどで現れる値です。
| 左の値 | `左 || "既定"` | `左 ?? "既定"` |
|---|---|---|
| `0` | `"既定"` | `0` |
| `""` | `"既定"` | `""` |
| `false` | `"既定"` | `false` |
| `null` | `"既定"` | `"既定"` |
| `undefined` | `"既定"` | `"既定"` |
| `NaN` | `"既定"` | `NaN` |
表の `""` は長さ0の文字列、`NaN` は数値として計算できない結果などを表します。どちらも `??` ならそのまま残ります。たとえば在庫数の `0` は「品切れ」という意味のある値です。
ブラウザーで0・空文字・falseを比較してみる
Chromeなどの開発者ツールで Console を開き、次のコードをそのまま貼って実行してください。Node.jsが使える場合は `.js` ファイルへ保存して `node ファイル名.js` でも確認できます。
const stock = 0;
const nickname = "";
const checked = false;
console.log(stock || 10); // 10
console.log(stock ?? 10); // 0
console.log(nickname || "ゲスト"); // ゲスト
console.log(JSON.stringify(nickname ?? "ゲスト")); // 空文字列を示す "" を表示
console.log(checked || true); // true
console.log(checked ?? true); // false
console.log(null ?? "未設定"); // 未設定
ここで見たいのは `||` では `0`、空文字、`false` が右辺に置き換わる一方、`??` では元の値が残ることです。空文字はコンソールで見落としやすいため `JSON.stringify` を使って `""` と確認しています。
コードをコピーして終わりにせず、`stock` を `5`、`null`、`undefined` に変えて各行の結果を予想してから実行すると、条件の違いを理解しやすくなります。
入力フォームで値を消さないための選び方
件数・数量・ON/OFF状態のように `0` や `false` が意味を持つ場合、未設定だけを補う用途には `??` を選びます。一方、空文字も「未入力」として扱いたいなら、`??` だけでは不足です。
const submittedName = "";
const safeName = submittedName.trim() === ""
? "ゲスト"
: submittedName;
console.log(safeName); // ゲスト
この例は `submittedName` が文字列である前提です。`null` の可能性もあるなら先に `const submittedName = rawName ?? "";` のように扱いを決めてから `trim()` を呼びます。目的を決めずに `||` を使い続けると、正常な0やfalseまで変更してしまいます。
「??と||を一緒に書いたらエラー」の直し方
`??` と `||`(または `&&`)を括弧なしで直接混在させると、JavaScriptは SyntaxError を出します。演算する順番が曖昧にならないよう括弧で意図を明示してください。
const input = null;
const valueA = (input ?? 0) || 5;
const valueB = input ?? (0 || 5);
console.log(valueA, valueB); // 5 5
もし `SyntaxError: Unexpected token` などが出たら、最初に括弧と演算子の並びを確認します。`||` を残した結果、0を置き換えていないかも見直してください。また `unknownVariable ?? 5` のように存在しない変数を直接参照すると ReferenceError になり、`??` では直りません。
どう判断する?動作確認のチェック
- 0・空文字・falseを意味のある入力として残す → `??` を使う
- 空文字や0も「無効」として置き換えたい → 条件を明示する。`||` が本当に意図と合うか確認する
- 右辺に関数がある → 左辺が採用されたとき右辺の関数は呼ばれない点に注意する
- エラーが出た → コンソールの例外メッセージ、該当行、入力値を一つずつ再現する
`??` を使えば `false` も既定値になりますか?
なりません。`false ?? true` は false のままです。falseを変更したい場合はその条件を明示します。
`??` と `||` のどちらが新しい書き方ですか?
`??` は null / undefined 用の演算子です。新旧より、どの値を有効として残したいかで選びます。
次に学ぶこと・参考資料
次は `?.`(オプショナルチェーン)を学ぶと、値がない可能性があるオブジェクトの読み出しと `??` を組み合わせて理解できます。`undefined` が出る原因から復習する場合は関連する公開記事も参照してください。
(undefinedが表示される原因と、プロパティ読み出しの確認方法については『なぜ「undefined」が出る?原因と解決法10選』をご参照ください)