JavaScriptの開発において、論理演算子はプログラムの挙動を制御するための極めて重要な要素です。
特に論理和(||)演算子は、条件分岐だけでなく、変数の初期化やデフォルト値の設定といったシーンで日常的に活用されています。
しかし、JavaScript特有の「真偽値の評価ルール」を正確に理解していないと、予期せぬバグを引き起こす原因にもなりかねません。
本記事では、2026年現在のモダンな開発環境を前提に、論理和演算子の基本的な使い方から、Null合体演算子(??)との明確な使い分けまでを詳しく解説します。
JavaScriptの論理和(||)演算子とは
論理和演算子(||)は、一般的に「OR演算子」と呼ばれ、複数の条件のうち少なくとも一つが真であるかを確認するために使用されます。
多くのプログラミング言語ではブール値(trueまたはfalse)のみを返しますが、JavaScriptの論理和演算子は「最後に評価された値そのもの」を返すという特徴を持っています。
基本的な構文と動作
論理和演算子の基本的な構文は、2つのオペランドを記号で繋ぐ形になります。
const result = value1 || value2;
このコードにおいて、JavaScriptエンジンはまず左側の value1 を評価します。
value1 が「真(truthy)」と判定された場合、エンジンは右側の value2 を評価することなく、即座に value1 の値を返します。
逆に value1 が「偽(falsy)」と判定された場合には、右側の value2 を評価し、その結果を返します。
短絡評価(ショートサーキット)の仕組み
この「左側が真であれば右側を評価しない」という仕組みは、短絡評価(ショートサーキット)と呼ばれます。
短絡評価を利用することで、特定の条件が満たされた場合にのみ後続の処理を実行させるような記述が可能になります。
// ユーザーが存在する場合のみ、その名前を表示する例
const user = { name: "田中" };
const displayName = user.name || "名無しさん";
console.log(displayName);
田中
この仕組みは、関数の実行を制御する際にも頻繁に利用されます。
JavaScriptにおける「偽(falsy)」の値
論理和演算子を使いこなす上で最も重要なのが、JavaScriptにおける「falsy(偽とみなされる値)」の定義を理解することです。
論理和演算子は、左側の値が以下のいずれかである場合に、右側の値を採用します。
false(ブール値の偽)0(数値のゼロ)-0(マイナスのゼロ)0n(BigIntのゼロ)""(空文字)null(値が存在しないことを示す)undefined(値が定義されていない)NaN(Not-a-Number)
これらの値は、論理評価のコンテキストにおいてすべて「偽」として扱われます。
特に、数値の 0 や空文字 "" が偽として扱われる点は、デフォルト値を設定する際に意図しない挙動を生む最大の要因となります。
デフォルト値の設定における論理和演算子の活用
論理和演算子の最も一般的なユースケースは、変数に対してデフォルト値を設定することです。
外部APIから取得したデータが欠損している場合や、関数の引数が省略された場合に備えて、安全な初期値を代入するために使われます。
基本的な初期化のパターン
以下の例では、設定オブジェクトから値を取得し、存在しない場合にデフォルト値を設定しています。
function setupConfig(options) {
// options.timeout が未定義(undefined)なら 3000 を代入
const timeout = options.timeout || 3000;
console.log(`タイムアウト設定: ${timeout}ms`);
}
setupConfig({ timeout: 5000 });
setupConfig({});
タイムアウト設定: 5000ms
タイムアウト設定: 3000ms
この書き方は非常に簡潔であり、多くのJavaScriptプロジェクトで長年採用されてきました。
論理和演算子によるデフォルト設定の落とし穴
しかし、論理和演算子をデフォルト値の設定に使う際には注意が必要です。
前述の通り、0 や "" も「偽」として判定されるため、これらが有効な値として渡された場合でもデフォルト値に上書きされてしまいます。
function setVolume(volume) {
// volumeに 0 を指定しても、偽と判定されて 50 が採用されてしまう
const currentVolume = volume || 50;
console.log(`音量: ${currentVolume}`);
}
setVolume(0);
音量: 50
この例では、ユーザーが明示的に音量を「0」に設定したにもかかわらず、システム側で「50」に書き換わってしまっています。
このような挙動は、多くの場合においてバグの原因となります。
Null合体演算子(??)との使い分け
上述した || の弱点を克服するために導入されたのが、Null合体演算子(??)です。
2026年現在のモダンな開発では、この2つの演算子を目的によって厳格に使い分けることが求められます。
Null合体演算子(??)の挙動
?? 演算子は、左側の値が null または undefined の場合にのみ右側の値を返します。
それ以外の 0、""、false といった値は「有効な値」としてそのまま返されます。
const userVolume = 0;
const volumeWithOR = userVolume || 50; // 50 になる
const volumeWithNullish = userVolume ?? 50; // 0 になる
console.log(`ORの場合: ${volumeWithOR}`);
console.log(`Null合体の場合: ${volumeWithNullish}`);
ORの場合: 50
Null合体の場合: 0
どちらを使うべきかの判断基準
使い分けの基準を以下の表にまとめました。
| 演算子 | 判定対象(左辺が何なら右辺を返すか) | 主な用途 |
|---|---|---|
|| (論理和) | すべてのfalsyな値 (0, "", false, null, undefined) | 「何かしらの値が存在すること」を重視する場合 |
?? (Null合体) | null または undefined のみ | 「値が未定義であること」のみをチェックしたい場合 |
基本的には ?? を優先的に使用するのが現代的なベストプラクティスです。
|| を使用するのは、「空文字や 0 も無効なデータとして扱いたい」という明確な意図がある場合に限定すべきです。
論理和代入演算子(||=)の活用
ES2021で導入された論理和代入演算子(||=)についても触れておきます。
これは、変数自体が偽である場合にのみ、新しい値を代入するための簡略化された記法です。
コードの簡略化
従来は以下のように書いていたコードを、よりスマートに記述できます。
let message = "";
// 従来の書き方
if (!message) {
message = "デフォルトメッセージ";
}
// 論理和代入演算子を使った書き方
message ||= "デフォルトメッセージ";
console.log(message);
デフォルトメッセージ
この演算子は、特に「キャッシュが存在しない場合に初期化する」といったロジックで非常に役立ちます。
ただし、これも || と同様の判定ルールに基づいているため、0 が入っている変数を上書きしてしまうリスクには注意が必要です。
実践的なユースケース
実際のアプリケーション開発において、論理和演算子がどのように使われるかをより具体的に見ていきましょう。
APIレスポンスの正規化
外部APIから取得したデータに一部の項目が足りない場合、UIが壊れないように代替テキストを表示することがあります。
const apiResponse = {
data: {
title: "",
description: null
}
};
// タイトルが空文字なら「タイトル未設定」にする
const pageTitle = apiResponse.data.title || "タイトル未設定";
// 説明がnullなら「詳細はありません」にする
const pageDesc = apiResponse.data.description ?? "詳細はありません";
console.log(`タイトル: ${pageTitle}`);
console.log(`説明: ${pageDesc}`);
タイトル: タイトル未設定
説明: 詳細はありません
この例では、空文字を許容したくないタイトルには || を使い、データが存在しない場合のみを考慮したい説明文には ?? を使い分けています。
条件付きの関数実行
特定のフラグが立っている場合や、オブジェクトが存在する場合にのみ後続のメソッドを呼び出すパターンです。
厳密には &&(論理積)の方がこの用途には多いですが、|| も「エラーが発生した際のフォールバック」として使われます。
function getSafeData() {
return null; // 何らかの理由で取得失敗
}
// データの取得に失敗した(nullを返した)場合、空配列をベースにする
const list = getSafeData() || [];
list.forEach(item => console.log(item));
この記述により、null に対して forEach を呼び出してエラー(TypeError)が発生する事態を防ぐことができます。
パフォーマンスと注意点
論理和演算子は非常に高速な演算子ですが、過度な乱用はコードの可読性を損なう可能性があります。
連鎖させすぎない
論理和演算子を何個も繋げてデフォルト値を決定するコードは、評価順序が直感的に分かりにくくなります。
const theme = userSetting.theme || localConfig.theme || globalConfig.theme || "light";
このような連鎖は便利ですが、どの階層で値が確定したのかをデバッグするのが難しくなるため、3つ以上の連鎖が必要な場合は、明示的な条件分岐や設定オブジェクトのマージ(Object.assignなど)を検討してください。
型の混在に注意する
JavaScriptは動的型付け言語であるため、|| の左右で異なる型を置くことができてしまいます。
数値が入るべき場所に文字列のデフォルト値を設定すると、後の計算で NaN が発生するなどのトラブルにつながります。
「常に同じ型の値を返すように設計する」のが、保守性の高いコードを書くための秘訣です。
まとめ
JavaScriptの論理和(||)演算子は、プログラムの柔軟性を高める非常に便利なツールです。
左辺が偽(falsy)であれば右辺を返すというシンプルなルールですが、その「偽」に含まれる範囲を正しく理解することが、バグのない実装への第一歩となります。
現代のJavaScript開発においては、以下のポイントを常に意識してください。
- 0や空文字を有効な値として扱いたい場合は、
||ではなく??を使用する。 - 短絡評価を活用して、不要な計算やエラーを防ぐコードを書く。
||=などの代入演算子を活用して、コードの記述をシンプルに保つ。- 型の一貫性を保ち、予期せぬ挙動を未然に防ぐ。
演算子の特性を正しく理解し、適切に使い分けることで、より堅牢で読みやすいJavaScriptコードを記述できるようになります。
日々のコーディングの中で、今使っている || が本当に適切かどうか、一度立ち止まって考えてみる習慣をつけましょう。
