Nullish Coalescing (??) と論理 OR (||) の違い
JavaScriptにおいてデフォルト値を設定する際、??
(nullish coalescing)と||
(論理 OR)は似たような挙動に見えますが、重要な違いがあります。この記事では両者の違いを明確にし、適切な使い分け方を解説します。
問題の核心
||
演算子は左側の値がfalsy(偽と見なされる値)の場合に右側の値を返します。一方、??
演算子は左側の値がnullish(null
またはundefined
)の場合のみ右側の値を返します。
let userAge = null;
// 両方とも21を返す
let age1 = userAge || 21; // 21
let age2 = userAge ?? 21; // 21
しかし、値がfalsyだがnullishではない場合、挙動が異なります。
基本的な違い
論理 OR (||
) の挙動
||
は左側の値がfalsy(false
, 0
, ""
, null
, undefined
, NaN
など)の場合、右側の値を返します。
console.log(0 || "デフォルト値"); // "デフォルト値"
console.log("" || "デフォルト値"); // "デフォルト値"
console.log(false || "デフォルト値"); // "デフォルト値"
console.log(null || "デフォルト値"); // "デフォルト値"
console.log(undefined || "デフォルト値"); // "デフォルト値"
Nullish Coalescing (??
) の挙動
??
は左側の値がnull
またはundefined
の場合のみ、右側の値を返します。
console.log(0 ?? "デフォルト値"); // 0
console.log("" ?? "デフォルト値"); // ""
console.log(false ?? "デフォルト値"); // false
console.log(null ?? "デフォルト値"); // "デフォルト値"
console.log(undefined ?? "デフォルト値"); // "デフォルト値"
覚え方
||
:「左がfalsyなら右を返す」??
:「左がnullまたはundefinedなら右を返す」
実用例での違い
フォームデータの処理
ユーザー入力で空文字列を有効な値として扱いたい場合:
// 電話番号が空文字列の場合
const phone = '';
// || を使うと問題が発生
phone || doSomething(); // doSomething()が実行されてしまう
// ?? を使うと正しく動作
phone ?? doSomething(); // phoneは空文字だが有効な値なのでdoSomething()は実行されない
数値の0を扱う場合
function updateAge(years) {
// || を使うと0が無視される
const yearsToAdd = years || 1; // yearsが0の場合、1になってしまう
// ?? を使うと0が正しく扱われる
const yearsToAddCorrect = years ?? 1; // yearsが0の場合、0のまま
return this.age + yearsToAddCorrect;
}
APIからのデータ取得
// Angularでの例
ngOnInit(): void {
// クエリパラメータがnullまたはundefinedの場合のみデフォルト値を使う
const keyword = this.route.snapshot.queryParamMap.get('keyword') ?? 'default keyword';
const page = this.route.snapshot.queryParamMap.get('page') ?? '0';
this.queryResult$ = this.service.getQueryResult(keyword, +page);
}
使い分けのガイドライン
??
を使うべき場合
- 数値の0を有効な値として扱いたい場合
- 空文字列を有効な値として扱いたい場合
- 明示的に
null
またはundefined
の場合のみデフォルト値を適用したい場合
||
を使うべき場合
- すべてのfalsyな値をデフォルト値で置き換えたい場合
- 空文字列や0を無効な値と見なしたい場合
- 既存のコードベースで一貫して
||
が使用されている場合
注意点
??
はES2020で導入された比較的新しい演算子です。古いブラウザやNode.jsバージョン(Node 14以前)ではサポートされていない可能性があるため、対象環境を確認してください。TypeScript 3.7以降では利用可能です。
まとめ
以下の表で??
と||
の違いをまとめます:
| 入力値 | ||
の結果 | ??
の結果 | |--------|------------|------------| | null
| デフォルト値 | デフォルト値 | | undefined
| デフォルト値 | デフォルト値 | | 0
| デフォルト値 | 0
| | ""
(空文字) | デフォルト値 | ""
| | false
| デフォルト値 | false
| | true
| true
| true
| | "text"
| "text"
| "text"
|
一般的には、??
を使用することを推奨します。より予測可能な挙動をし、意図しないfalsy値の置き換えを防ぐことができます。特に、数値の0や空文字列を有効な値として扱う場合は、必ず??
を使用してください。
他の言語でも
Nullish coalescing演算子は他の言語でも見られます:
- PHP:
??
- C#:
??
- Swift:
??
これらの言語でも同様の挙動をします。