JavaScriptにおいて、論理演算子はプログラムの条件分岐や値の制御を行うための最も基礎的かつ重要な要素の一つです。
しかし、近年のECMAScriptのアップデートにより、単純な「かつ(AND)」や「または(OR)」といった概念を超え、コードの記述量を減らしつつ可読性を高めるための強力な演算子が数多く導入されています。
本記事では、基本的な論理演算子から、2026年現在のモダンな開発において必須となっているNull合体演算子(??)や論理代入演算子(&&=, ||=, ??=)までを、具体的な実例とともに解説します。
論理演算子の基礎知識と短絡評価の仕組み
JavaScriptの論理演算子を理解する上で欠かせないのが、「短絡評価(ショートサーキット評価)」という仕組みです。
これは、演算子が左側の値を評価した時点で結果が確定した場合、右側の評価を行わずに処理を終了する性質を指します。
基本的な3つの論理演算子
まずは、JavaScriptにおける基本の3要素である論理積、論理和、論理否定について整理しましょう。
論理積(&&)
&& 演算子は、すべての条件が true である場合にのみ真となります。
ただし、JavaScriptにおいては「最初に現れた偽(Falsy)な値を返す」か、「すべてが真(Truthy)であれば最後の値を返す」という挙動をします。
// 論理積の例
const a = 10;
const b = 20;
// 両方が真の場合、右側の値が返される
const result1 = (a > 0) && (b > 0);
console.log(result1);
// 左側が偽の場合、その時点で評価を終えて左側の値を返す
const result2 = 0 && "Hello";
console.log(result2);
true
0
論理和(||)
|| 演算子は、いずれかの条件が true であれば真となります。
挙動としては「最初に現れた真(Truthy)な値を返す」か、「すべてが偽であれば最後の値を返す」ことになります。
// 論理和の例
const name = "";
const defaultName = "ゲスト";
// nameが空文字(Falsy)なので、defaultNameが返される
const userName = name || defaultName;
console.log(userName);
"ゲスト"
論理否定(!)
! 演算子は、値を反転させます。
真を偽に、偽を真に変換します。
また、!! と二重に使用することで、任意の値を明示的にBoolean型に変換する手法もよく使われます。
// 論理否定の例
const isAdmin = true;
console.log(!isAdmin);
const value = "text";
// 文字列はTruthyなので、!!でtrueに変換される
console.log(!!value);
false
true
JavaScriptにおけるTruthyとFalsy
論理演算子を正確に使いこなすためには、どの値が false と見なされ、どの値が true と見なされるかを把握しておく必要があります。
JavaScriptでは、Boolean型の false 以外にも、偽として扱われる「Falsy」な値が存在します。
| 値 | 型 | 説明 |
|---|---|---|
false | Boolean | 論理値の偽 |
0 / -0 | Number | 数値のゼロ |
0n | BigInt | BigIntのゼロ |
"" | String | 空文字 |
null | Null | 値の欠如 |
undefined | Undefined | 未定義 |
NaN | Number | 非数 |
これら以外の値(空の配列 [] や空のオブジェクト {} を含む)はすべて Truthy(真) として扱われます。
特に空の配列が真として評価される点は、他言語の経験者が陥りやすいミスの一つです。
Null合体演算子(??)の重要性
モダンなJavaScript開発において、|| 演算子の代わりに頻繁に使われるようになったのが Null合体演算子(??) です。
|| 演算子の問題点
従来、変数のデフォルト値を設定する際には || が使われてきました。
しかし、|| は「Falsyな値すべて」を対象にするため、数値の 0 や空文字 “” を有効な値として扱いたい場合でも、デフォルト値に上書きしてしまう という問題がありました。
?? 演算子の挙動
?? 演算子は、左辺が null または undefined の場合にのみ右辺を評価し、それ以外(0 や空文字、false など)の場合は左辺の値をそのまま返します。
// Null合体演算子の比較
const userSettings = {
volume: 0,
theme: "",
retryCount: null
};
// || の場合:0を「値がない」と判断してしまう
const vol1 = userSettings.volume || 50;
// ?? の場合:0を有効な値として維持する
const vol2 = userSettings.volume ?? 50;
console.log(`|| の結果: ${vol1}`);
console.log(`?? の結果: ${vol2}`);
const retry = userSettings.retryCount ?? 3;
console.log(`retryCount: ${retry}`);
|| の結果: 50
?? の結果: 0
retryCount: 3
このように、ユーザー設定やAPIレスポンスの処理において「意図的な0」や「意図的な空文字」を保持したい場合には、?? を使用するのがベストプラクティスです。
論理代入演算子によるコードの簡略化
ES2021(ES12)で導入され、現在の開発現場で定着しているのが 論理代入演算子(Logical Assignment Operators) です。
これは、算術代入演算子(+= など)と同様に、論理演算と代入を組み合わせたものです。
論理和代入演算子(||=)
左辺が Falsy である場合にのみ、右辺の値を代入します。
let config = { timeout: 0 };
// config.timeoutが0 (Falsy) なので、3000が代入される
config.timeout ||= 3000;
let title = "";
title ||= "名称未設定";
console.log(config.timeout);
console.log(title);
3000
"名称未設定"
論理積代入演算子(&&=)
左辺が Truthy である場合にのみ、右辺の値を代入します。
これは特定のオブジェクトが存在する場合にのみプロパティを上書きしたい、といったケースに便利です。
let user = { active: true, name: "Alice" };
// user.activeがtrueなので、nameが"Active User"に更新される
user.active &&= "Active User";
let guest = { active: false, name: "Guest" };
guest.active &&= "Active User";
console.log(user.active);
console.log(guest.active);
"Active User"
false
Null合体代入演算子(??=)
左辺が null または undefined の場合にのみ、右辺の値を代入します。
初期化処理において最も安全に使用できる演算子です。
let cache = null;
// cacheがnullなので代入される
cache ??= "初期データ";
console.log(cache);
// すでに値がある場合は上書きされない
cache ??= "新しいデータ";
console.log(cache);
"初期データ"
"初期データ"
実践的な活用シーン:安全なプロパティアクセスと初期化
実際のアプリケーション開発では、これらの論理演算子を組み合わせることで、エラーに強く読みやすいコードを記述できます。
特に、2026年時点では 「オプショナルチェイニング(?.)」 と論理演算子の組み合わせは標準的な手法となっています。
オプショナルチェイニングとの組み合わせ
ネストされたオブジェクトから値を取得し、値が存在しない場合にデフォルト値を設定するパターンは非常に頻出します。
const response = {
data: {
user: {
profile: {
bio: ""
}
}
}
};
// bioがnull/undefined、あるいは空文字などの場合にデフォルトを設定
// ?. で安全にアクセスし、?? でフォールバック
const bioText = response.data?.user?.profile?.bio ?? "自己紹介は未設定です。";
console.log(bioText);
""
※上記の例では ?? を使用しているため、空文字 "" は有効な値として扱われます。
もし「空文字の場合もデフォルト値を出したい」のであれば、|| を選択するのが適切です。
短絡評価による関数実行の制御
特定の条件を満たしているときだけ関数を実行したい場合、if 文を書く代わりに && を利用することがあります。
const isLoggable = true;
const message = "システムを起動します";
// isLoggableがtrueのときだけ、右辺のconsole.logが実行される
isLoggable && console.log(message);
ただし、この記法は React の JSX 内などで多用されますが、あまりに複雑なロジックを詰め込むと可読性が低下するため、「一目で副作用が理解できる範囲」に留めるのが賢明です。
注意すべき優先順位とベストプラクティス
演算子には優先順位があり、複数の演算子を組み合わせる際には注意が必要です。
特に ?? は && や || と直接混ぜて使うことができず、括弧 () で明示的に優先順位を指定しなければ構文エラーとなります。
演算子の混合に関するルール
// エラーになる例
// const value = a && b ?? c; // SyntaxError
// 正しい例
const value = (a && b) ?? c;
JavaScriptのエンジンは、開発者が「ANDを先に計算したいのか、Null合体を先にしたいのか」を明確にすることを求めています。
コードの可読性を保つための指針
- 目的を明確にする:存在チェック(null/undefined)なら
??、真偽値による分岐なら||を使い分けます。 - 副作用に注意する:短絡評価を利用して関数を呼び出す場合、その関数が予期せぬ状態変更(副作用)を起こさないか確認してください。
- 論理代入で冗長さを排除する:
x = x || yと書くよりもx ||= yと書く方が、変数の重複がなくタイポを防げます。
まとめ
JavaScriptの論理演算子は、単なる条件判定の道具から、データ構造の初期化や安全なアクセスを支える重要なパーツへと進化しました。
- 基本の &&, ||, ! は短絡評価の仕組みを理解して使うことが重要です。
- Null合体演算子(??) は、0 や空文字を許容したい現代的な開発において
||よりも安全な選択肢となります。 - 論理代入演算子(||=, &&=, ??=) を活用することで、コードをより簡潔かつ宣言的に記述できます。
- Falsyな値 の定義を正確に把握することが、バグの少ないプログラミングへの第一歩です。
これらの演算子を適切に使い分けることで、2026年のJavaScript開発において、よりクリーンでメンテナンス性の高いソースコードを記述できるようになります。
それぞれの演算子が持つ「評価のタイミング」と「返り値の性質」を意識しながら、日々のコーディングに取り入れてみてください。
