JavaScriptにおける論理和演算子「||」の深淵:単なる「OR」ではない挙動の仕組み
JavaScriptにおける論理和演算子「||」は、初心者からベテランまで多くのエンジニアが日常的に使用するツールです。しかし、その挙動を「真か偽を返すもの」と単純に理解していると、予期せぬバグに遭遇することがあります。本記事では、JavaScriptの「||」演算子が内部的にどのように値を評価し、どのような結果を返すのか、その本質的な仕組みを徹底的に解説します。
論理和演算子「||」の基本定義と短絡評価
多くのプログラミング言語において、論理演算子は真偽値(Boolean)を返します。しかし、JavaScriptの「||」演算子は、どちらか一方の「値そのもの」を返します。
論理和演算子「a || b」の挙動は以下の通りです。
1. 左側のオペランド(a)を評価します。
2. もしaが「真値(Truthy)」であれば、aをそのまま返します。
3. もしaが「偽値(Falsy)」であれば、bを評価し、その結果を返します。
ここで重要なのは、左側が真値であると判定された瞬間、右側の評価は行われないという点です。これを「短絡評価(Short-circuit evaluation)」と呼びます。例えば、「a || b」においてaが真であれば、bが関数呼び出しであっても実行されることはありません。これはパフォーマンス最適化や、条件付き実行において非常に強力なパターンです。
TruthyとFalsyの境界線
「||」演算子の結果を正しく予測するためには、JavaScriptにおける「偽値(Falsy)」のリストを完全に把握しておく必要があります。これら以外の値はすべて「真値(Truthy)」として扱われます。
JavaScriptにおけるFalsyな値は以下の7つです。
– false
– 0 (数値のゼロ)
– -0 (負のゼロ)
– 0n (BigIntのゼロ)
– “” (空文字列)
– null
– undefined
– NaN (Not a Number)
これら以外の値、例えば空のオブジェクト「{}」、空の配列「[]」、あるいは文字列の「”0″」などはすべて真値として扱われます。この仕様が、論理和演算子の結果を直感から遠ざける最大の要因です。
実務における挙動の検証とサンプルコード
以下のコードは、開発現場で頻出する「デフォルト値の設定」を模した例です。
// デフォルト値の代入パターン
function getConfiguration(userSetting) {
// userSettingがFalsy(null, undefined, 0, ""など)の場合、デフォルト値が適用される
const theme = userSetting || "light";
return theme;
}
console.log(getConfiguration("dark")); // "dark"
console.log(getConfiguration(null)); // "light"
console.log(getConfiguration(undefined)); // "light"
console.log(getConfiguration(0)); // "light" (注意!)
console.log(getConfiguration("")); // "light" (注意!)
上記のコードにおける0や空文字列の扱いに注目してください。ビジネスロジック上、「0」という設定値が有効であるにもかかわらず、「||」演算子を使うと強制的にデフォルト値に上書きされてしまいます。これが、論理和演算子をデフォルト値の設定に使う際の最大の落とし穴です。
Null合体演算子「??」との使い分け
前述の「0」や「””」が意図せずデフォルト値に置き換わってしまう問題を解決するために、ES2020で導入されたのが「Null合体演算子(??)」です。
「a ?? b」は、「aがnullまたはundefinedの場合にのみbを返す」という挙動をします。これにより、0や空文字列を「有効な値」として保持したい場合に安全なコードを書くことが可能になります。
function getSafeConfiguration(userSetting) {
// ?? は null または undefined の場合のみ右側を評価する
const theme = userSetting ?? "light";
return theme;
}
console.log(getSafeConfiguration(0)); // 0 (期待通り)
console.log(getSafeConfiguration("")); // "" (期待通り)
console.log(getSafeConfiguration(null)); // "light"
実務においては、単なる「OR」として「||」を使うのではなく、その値が「Falsyであっても許容されるのか」を常に自問自答する必要があります。
フロントエンド開発における実務アドバイス
実務の現場では、以下のガイドラインに従うことを推奨します。
1. DOM要素のプロパティやAPIの戻り値に対してデフォルト値を設定する場合、可能であれば「??」を優先的に使用してください。
2. 「||」は、あくまで「空値(Falsy)を排除し、有効な値を抽出する」という意図が明確な場合にのみ使用します。
3. 条件分岐(if文)においては、結果がBooleanに変換されるため「||」を使用しても問題ありませんが、代入演算として使用する場合は、その値の型を慎重に検討してください。
4. TypeScriptを使用している場合、型定義によって「undefined」や「null」の可能性をコンパイル時に検知できるため、論理演算子の挙動に依存しすぎない堅牢なコード設計が可能です。
まとめ
JavaScriptの論理和演算子「||」は、単なる条件分岐のツールではなく、左側の値が「Falsyか否か」で制御フローを決定する強力な値のフィルタリング機構です。
– 「||」は最初の真値を返し、そうでなければ最後の値を返す。
– 0, “”, null, undefined, false, NaN はすべて偽値として扱われる。
– デフォルト値の代入には、意図しない挙動を防ぐために「??」演算子の活用を検討する。
この演算子の挙動を深く理解することは、JavaScriptの非同期処理や状態管理におけるバグを未然に防ぐための第一歩です。言語仕様の表面的な理解にとどまらず、その背後にある評価エンジンを意識することで、よりクリーンで予測可能なコードを書くことができるようになるでしょう。フロントエンド・スペシャリストとして、常に「この値はFalsyになり得るか?」という視点を忘れないようにしてください。

コメント