JavaScriptで条件を組み合わせるには論理演算子(&&・||・!)を使います。「AかつB」「AまたはB」「Aではない」といった条件分岐は、あらゆるプログラムの基本です。
この記事では、AND・OR・NOT演算子の基本的な使い方から、短絡評価の仕組み、ES2020で追加されたNull合体演算子(??)とOptional Chaining(?.)、実務で頻出するパターンまで体系的に解説します。
この記事で学べること
- 論理演算子(
&&・||・!)の基本と評価ルール
- 短絡評価(ショートサーキット)の仕組みと活用法
- 論理演算子が「値を返す」メカニズム
- Null合体演算子(
??)と || の違い
- Optional Chaining(
?.)の使い方
- フォームバリデーション・権限チェック等の実務パターン
- falsyな値・演算子の優先順位・よくあるミス
論理演算子の一覧と基本
JavaScriptには3つの論理演算子があります。それぞれの役割を確認しましょう。
| 演算子 |
名前 |
意味 |
例 |
| && |
AND(論理積) |
両方trueならtrue |
a && b |
| || |
OR(論理和) |
どちらかがtrueならtrue |
a || b |
| ! |
NOT(論理否定) |
true/falseを反転 |
!a |
真偽値(truthy / falsy)の評価ルール
論理演算子を理解するには、JavaScriptのtruthy(真と評価される値)とfalsy(偽と評価される値)の概念が重要です。
ポイント:falsyな値は6つだけ
false、0(と -0)、""(空文字列)、null、undefined、NaN の6つがfalsyです。それ以外はすべてtruthy(空配列 [] や空オブジェクト {} もtruthy)です。
truthy / falsy の確認
// falsyな値(6つ)
Boolean(false); // false
Boolean(0); // false
Boolean(''); // false(空文字列)
Boolean(null); // false
Boolean(undefined); // false
Boolean(NaN); // false
// truthyな値(上記以外すべて)
Boolean(1); // true
Boolean('hello'); // true
Boolean([]); // true(空配列もtruthy!)
Boolean({}); // true(空オブジェクトもtruthy!)
Boolean('0'); // true(文字列の"0"はtruthy!)
AND演算子(&&)の使い方
&&(AND演算子)は、両方の条件がtrueのときだけtrueを返す演算子です。「AかつB」を表現するときに使います。
基本的な使い方:複数条件の組み合わせ
AND演算子の基本
const age = 25;
const hasLicense = true;
// 両方の条件を満たすかチェック
if (age >= 18 && hasLicense) {
console.log('運転できます');
}
// => "運転できます"
// 3つ以上の条件も連結可能
const user = { age: 20, isVerified: true, country: 'JP' };
if (user.age >= 18 && user.isVerified && user.country === 'JP') {
console.log('サービスを利用できます');
}
// => "サービスを利用できます"
短絡評価(ショートサーキット)
&& には短絡評価という重要な特性があります。左辺がfalsyなら、右辺は評価せずに左辺の値をそのまま返します。
&&の短絡評価
// 左辺がfalsyなら右辺は実行されない
false && console.log('表示されない');
// 何も表示されない(右辺が評価されない)
true && console.log('表示される');
// => "表示される"(左辺がtruthyなので右辺も評価)
// 実用例:オブジェクトの存在チェック
const user = null;
user && console.log(user.name);
// userがnull(falsy)なので右辺は実行されず、エラーにならない
&& は「値を返す」演算子
重要なポイントとして、&& は true / false を返すのではなく、評価が止まった時点の値そのものを返します。
&&が返す値
// 左辺がfalsyなら → 左辺の値を返す
0 && 'hello'; // 0
'' && 'hello'; // ""
null && 'hello'; // null
undefined && 'hello'; // undefined
// 左辺がtruthyなら → 右辺の値を返す
1 && 'hello'; // "hello"
'abc' && 42; // 42
true && 'world'; // "world"
// 3つ以上の場合:最初のfalsyを返す。全部truthyなら最後の値
1 && 2 && 3; // 3(全部truthy → 最後の値)
1 && 0 && 3; // 0(最初のfalsyで止まる)
1 && '' && 3; // ""(最初のfalsyで止まる)
| 式 |
評価プロセス |
結果 |
| true && true |
左がtruthy → 右を返す |
true |
| true && false |
左がtruthy → 右を返す |
false |
| false && true |
左がfalsy → 左を返す(右は無視) |
false |
| false && false |
左がfalsy → 左を返す(右は無視) |
false |
OR演算子(||)の使い方
||(OR演算子)は、どちらか一方でもtrueならtrueを返す演算子です。「AまたはB」を表現するときに使います。
基本的な使い方:複数条件の組み合わせ
OR演算子の基本
const day = 'Saturday';
// どちらかの条件を満たせばOK
if (day === 'Saturday' || day === 'Sunday') {
console.log('週末です');
}
// => "週末です"
// 3つ以上の条件
const ext = '.png';
if (ext === '.jpg' || ext === '.png' || ext === '.gif') {
console.log('画像ファイルです');
}
// => "画像ファイルです"
短絡評価(ショートサーキット)
|| は && の逆で、左辺がtruthyなら右辺を評価せずに左辺の値を返します。
||の短絡評価
// 左辺がtruthyなら → 左辺の値を返す(右辺は無視)
'hello' || 'world'; // "hello"
1 || 2; // 1
true || false; // true
// 左辺がfalsyなら → 右辺の値を返す
0 || 'default'; // "default"
'' || 'fallback'; // "fallback"
null || '代わりの値'; // "代わりの値"
// 3つ以上の場合:最初のtruthyを返す。全部falsyなら最後の値
0 || '' || 'hello'; // "hello"(最初のtruthy)
0 || '' || null; // null(全部falsy → 最後の値)
デフォルト値の設定パターン
|| の短絡評価を活用したデフォルト値パターンは非常によく使われます。
||でデフォルト値を設定
// 関数の引数にデフォルト値を設定
function greet(name) {
name = name || 'ゲスト';
console.log('こんにちは、' + name + 'さん');
}
greet('太郎'); // "こんにちは、太郎さん"
greet(); // "こんにちは、ゲストさん"(undefinedはfalsy)
greet(null); // "こんにちは、ゲストさん"(nullもfalsy)
// 設定値の読み込み
const config = {};
const port = config.port || 3000;
console.log(port); // 3000(config.portはundefined → falsy)
注意:|| によるデフォルト値設定には落とし穴があります。0 や ""(空文字列)も falsy なので、これらを有効な値として使いたい場合は意図しない動作になります。この問題を解決するのが後述のNull合体演算子(??)です。
| 式 |
評価プロセス |
結果 |
| true || true |
左がtruthy → 左を返す(右は無視) |
true |
| true || false |
左がtruthy → 左を返す(右は無視) |
true |
| false || true |
左がfalsy → 右を返す |
true |
| false || false |
左がfalsy → 右を返す |
false |
NOT演算子(!)の使い方
!(NOT演算子)は、値の真偽を反転させる演算子です。truthyな値をfalseに、falsyな値をtrueに変換します。
基本的な使い方:否定
NOT演算子の基本
// true/false の反転
!true; // false
!false; // true
// 条件の否定
const isLoggedIn = false;
if (!isLoggedIn) {
console.log('ログインしてください');
}
// => "ログインしてください"
// truthyな値をfalseに変換
!'hello'; // false(文字列はtruthy → 反転してfalse)
!42; // false
![]; // false(空配列もtruthy → false)
// falsyな値をtrueに変換
!0; // true
!''; // true
!null; // true
!undefined; // true
!!(二重否定)でbooleanに変換
! を2回使う二重否定(!!)は、任意の値をboolean型に変換するテクニックです。Boolean() と同じ結果になります。
!! でboolean変換
// !!で任意の値をbooleanに変換
!!'hello'; // true("hello" → false → true)
!!0; // false(0 → true → false)
!!null; // false
!!undefined; // false
!!1; // true
!![]; // true
!!{}; // true
// Boolean()と同じ結果
!!'hello' === Boolean('hello'); // true
!!0 === Boolean(0); // true
// 実用例:APIレスポンスの存在チェック
const data = fetchData();
const hasData = !!data; // booleanとして保存
!! vs Boolean() どちらを使うべき?
どちらも結果は同じですが、Boolean() の方が意図が明確です。チームのコーディング規約に合わせましょう。!! はコードが短いため、条件式の中でよく使われます。
Null合体演算子(??)とOptional Chaining(?.)
ES2020で追加されたNull合体演算子(??)とOptional Chaining(?.)は、|| の欠点を補う強力な演算子です。
Null合体演算子(??):||との違い
?? は、左辺がnull または undefined のときだけ右辺の値を返します。|| との最大の違いは、0 や ""(空文字列)を有効な値として扱う点です。
?? vs || の違い
// || はfalsyな値すべてでデフォルト値を使う
0 || 10; // 10 (0はfalsy → 意図しない!)
'' || 'default'; // "default"(空文字もfalsy → 意図しない!)
null || 10; // 10
// ?? はnull/undefinedのときだけデフォルト値を使う
0 ?? 10; // 0 (0はnullでもundefinedでもない → そのまま)
'' ?? 'default'; // "" (空文字もそのまま)
false ?? true; // false(falseもそのまま)
null ?? 10; // 10 (nullなのでデフォルト値を使う)
undefined ?? 10; // 10 (undefinedなのでデフォルト値を使う)
??の実用例
// ユーザー設定の読み込み(0や空文字を有効な値として扱う)
const userSettings = {
volume: 0, // 0は「ミュート」として有効な値
nickname: '', // 空文字は「ニックネーム未設定」として有効
theme: null, // nullは「未設定」
};
// || だと0や空文字がデフォルト値に置き換わってしまう
const vol1 = userSettings.volume || 50; // 50(0がfalsyなので意図しない!)
const nick1 = userSettings.nickname || '匿名'; // "匿名"(空文字がfalsyなので意図しない!)
// ?? なら正しく動く
const vol2 = userSettings.volume ?? 50; // 0(意図通り)
const nick2 = userSettings.nickname ?? '匿名'; // ""(意図通り)
const theme = userSettings.theme ?? 'light'; // "light"(nullなのでデフォルト値)
| 左辺の値 |
|| の結果 |
?? の結果 |
| null |
右辺を返す |
右辺を返す |
| undefined |
右辺を返す |
右辺を返す |
| 0 |
右辺を返す |
0を返す |
| “”(空文字) |
右辺を返す |
“”を返す |
| false |
右辺を返す |
falseを返す |
Optional Chaining(?.)の使い方
?.(Optional Chaining)は、オブジェクトのプロパティに安全にアクセスするための演算子です。途中のプロパティがnull / undefinedの場合、エラーにならずundefinedを返します。
Optional Chaining の基本
const user = {
name: '太郎',
address: {
city: '東京'
}
};
// 従来の書き方(&&で安全にアクセス)
const city1 = user && user.address && user.address.city;
console.log(city1); // "東京"
// Optional Chainingを使った書き方
const city2 = user?.address?.city;
console.log(city2); // "東京"
// 存在しないプロパティにアクセスしてもエラーにならない
const zip = user?.address?.zipCode;
console.log(zip); // undefined(エラーにならない)
// nullのオブジェクトでも安全
const guest = null;
console.log(guest?.name); // undefined
console.log(guest?.address?.city); // undefined
?.のさまざまな使い方
const user = {
getName() { return '太郎'; },
scores: [80, 90, 100]
};
// メソッド呼び出し
user.getName?.(); // "太郎"
user.getAge?.(); // undefined(メソッドが無くてもエラーにならない)
// 配列アクセス
user.scores?.[0]; // 80
user.grades?.[0]; // undefined
// ??と組み合わせてデフォルト値を設定
const city = user?.address?.city ?? '不明';
console.log(city); // "不明"(addressがないのでundefined → ??でデフォルト値)
ポイント:?. と ?? の組み合わせが最強
user?.address?.city ?? '不明' のように、?. で安全にアクセスしつつ ?? でデフォルト値を設定するパターンは、モダンJavaScriptで非常によく使われます。
実務でよく使うパターン
論理演算子は条件分岐以外にも、さまざまな場面で活用できます。実務で頻出するパターンを見ていきましょう。
フォームバリデーション(複数条件の組み合わせ)
フォームバリデーション
function validateForm(form) {
const errors = [];
// AND: すべての条件を満たす必要がある
if (!form.name || form.name.length < 2) {
errors.push('名前は2文字以上で入力してください');
}
// メールアドレスの形式チェック
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!form.email || !emailRegex.test(form.email)) {
errors.push('有効なメールアドレスを入力してください');
}
// パスワードの複数条件チェック
if (
form.password.length >= 8 &&
/[A-Z]/.test(form.password) &&
/[0-9]/.test(form.password)
) {
console.log('パスワードOK');
} else {
errors.push('パスワードは8文字以上、大文字と数字を含めてください');
}
return errors;
}
権限チェック
権限チェック
function canEditPost(user, post) {
// 管理者 または 投稿者本人 なら編集可能
return user.role === 'admin' || user.id === post.authorId;
}
function canAccessDashboard(user) {
// ログイン済み かつ メール認証済み かつ (管理者 または 編集者)
return (
user.isLoggedIn &&
user.isEmailVerified &&
(user.role === 'admin' || user.role === 'editor')
);
}
// 使用例
const user = { isLoggedIn: true, isEmailVerified: true, role: 'editor' };
console.log(canAccessDashboard(user)); // true
条件付きレンダリング(React)
React – JSX
// && を使った条件付きレンダリング
function UserProfile({ user, isLoading }) {
return (
<div>
{isLoading && <p>読み込み中...</p>}
{user && (
<div>
<h2>{user.name}</h2>
<p>{user.email}</p>
</div>
)}
{/* || でデフォルト表示 */}
<img src={user?.avatar || '/default-avatar.png'} />
{/* 三項演算子との使い分け */}
{user?.isAdmin ? <AdminPanel /> : <UserPanel />}
</div>
);
}
Reactで&&を使うときの注意
{count && <p>{count}件</p>} のように数値を左辺にすると、countが0のとき画面に「0」が表示されてしまいます。{count > 0 && <p>{count}件</p>} のように、明示的にbooleanにしましょう。
ガード節(早期リターン)
ガード節パターン
// 悪い例:ネストが深くなる
function processOrderBad(order) {
if (order) {
if (order.items.length > 0) {
if (order.isPaid) {
// メイン処理...
}
}
}
}
// 良い例:ガード節で早期リターン
function processOrderGood(order) {
if (!order) return;
if (order.items.length === 0) return;
if (!order.isPaid) return;
// メイン処理(ネストなし!)
console.log('注文を処理します');
}
よくあるミスと注意点
論理演算子を使ううえで、初心者がつまづきやすいポイントをまとめます。
= と == と === の違い
条件式で最も多いミスが、代入演算子(=)と比較演算子(== / ===)の混同です。
= vs == vs ===
let x = 5;
// = は代入(バグの原因!)
if (x = 10) { // xに10を代入。10はtruthy → 常にtrue!
console.log(x); // 10(xが書き換わっている)
}
// == は緩い比較(型変換あり)
5 == '5'; // true(文字列"5"を数値5に変換して比較)
0 == false; // true(falseを数値0に変換して比較)
'' == false; // true
null == undefined; // true
// === は厳密比較(型変換なし) ← 推奨!
5 === '5'; // false(型が違う)
0 === false; // false(型が違う)
null === undefined; // false(型が違う)
ポイント:常に === を使おう
特別な理由がない限り、比較には===(厳密等価演算子)を使いましょう。== は暗黙の型変換により予想外の結果になることがあります。ESLintの eqeqeq ルールで強制するのがベストプラクティスです。
falsyな値の一覧
論理演算子で条件チェックをするとき、意図せずfalsyになる値に注意が必要です。
| falsyな値 |
型 |
説明 |
よくあるケース |
| false |
boolean |
偽 |
フラグがOFF |
| 0 / -0 |
number |
ゼロ |
カウント0、音量0 |
| “”(空文字列) |
string |
空の文字列 |
未入力のフォーム |
| null |
object |
意図的な「値なし」 |
APIレスポンスが空 |
| undefined |
undefined |
未定義 |
未設定のプロパティ |
| NaN |
number |
数値でない |
parseInt("abc")の結果 |
演算子の優先順位(&&は||より先)
&& は || よりも優先順位が高いため、先に評価されます。意図しない結果を防ぐには、括弧()を使いましょう。
演算子の優先順位
// && は || より優先順位が高い
true || false && false;
// ↓ 内部的にはこう評価される
true || (false && false);
// true || false => true
// 意図が「(true || false) && false」なら括弧が必要
(true || false) && false;
// true && false => false
// 実務例:括弧で意図を明確に
const canAccess =
(role === 'admin' || role === 'editor') && isActive;
// ↑ 管理者か編集者 かつ アクティブ
| 優先順位 |
演算子 |
説明 |
| 1(高い) |
! |
NOT(単項演算子) |
| 2 |
&& |
AND |
| 3 |
|| |
OR |
| 4(低い) |
?? |
Null合体 |
注意:?? と || / && は直接混在できない
a || b ?? c のように ?? と ||(または &&)を括弧なしで併用するとSyntaxErrorになります。必ず (a || b) ?? c のように括弧で囲みましょう。
よくある質問(FAQ)
Q. &&と||演算子は条件判定だけでなく値の返し方にも特徴がありますか?
A. JavaScriptの&&は左辺がfalsyなら左辺を返し、truthyなら右辺を返します。||は左辺がtruthyなら左辺を返し、falsyなら右辺を返します。例:null || "default"は"default"、true && "value"は"value"。これを利用したデフォルト値設定や条件付き実行がよく使われます。
Q. ??(Nullish Coalescing)演算子と||の違いは何ですか?
A. ??は左辺がnullまたはundefinedのみの場合に右辺を返します。||は左辺がfalsy(0・””・false・null・undefined)のときに右辺を返します。数値の0や空文字””をデフォルト値として扱いたい場合は||ではなく??を使います。例:0 ?? 10は0、0 || 10は10。
Q. 短絡評価(ショートサーキット)とはどういう意味ですか?
A. 論理演算子は結果が確定した時点で残りの評価を停止します。false && 関数()は関数が呼ばれません(左辺がfalseで&&全体がfalse確定)。true || 関数()も関数が呼ばれません。これを利用してcondition && doSomething()のようにif文の代わりに使う書き方もあります。
まとめ:論理演算子・Null合体演算子 比較表
この記事で解説した演算子を一覧表にまとめます。
| 演算子 |
構文 |
返す値 |
主な用途 |
| AND |
a && b |
最初のfalsyな値、または最後の値 |
複数条件、条件付き実行 |
| OR |
a || b |
最初のtruthyな値、または最後の値 |
デフォルト値設定 |
| NOT |
!a |
boolean(反転した値) |
条件の否定、!!でboolean変換 |
| Null合体 |
a ?? b |
aがnull/undefinedなら b、それ以外は a |
0や空文字を有効値として扱う |
| Optional Chaining |
a?.b |
aがnull/undefinedならundefined、それ以外はa.b |
ネストしたプロパティの安全なアクセス |
この記事のまとめ
&&(AND)は両方trueのときtrue。短絡評価で左辺がfalsyなら右辺を無視
||(OR)はどちらかがtrueならtrue。デフォルト値の設定に便利
!(NOT)は真偽値を反転。!!でboolean変換ができる
??(Null合体)は || と違い、0や空文字を有効な値として扱う
?.(Optional Chaining)でネストしたプロパティに安全にアクセスできる
&& は || より優先順位が高い。迷ったら括弧を使う
- 比較は常に
===(厳密等価演算子)を使い、falsyな値の6つを覚えておく
論理演算子は、条件分岐だけでなく、デフォルト値の設定やガード節など、コードをシンプルに保つためのテクニックとしても活用できます。特に ?? と ?. はモダンJavaScript開発では必須知識なので、|| との違いをしっかり理解しておきましょう。