【JavaScript】if 文による条件分岐の書き方|else if・ネスト・論理演算子・truthy/falsy・実務パターンまで解説

【JavaScript】if 文による条件分岐の書き方|else if・ネスト・論理演算子・truthy/falsy・実務パターンまで解説 JavaScript

JavaScript の if 文は、プログラミングの最も基本的な制御構文です。条件に応じて処理を分岐させ、「もし〜ならば」「そうでなければ」というロジックを記述します。

本記事では、if 文の基本構文から、比較演算子・論理演算子truthy / falsy の判定ネストの回避テクニック三項演算子や switch 文との使い分けまで解説します。

この記事でわかること
・if / else / else if の基本構文
・比較演算子(== と === の違い)と論理演算子(&& / || / !)
・truthy / falsy の判定ルール
・if 文のネストと早期リターンによる回避
・オプショナルチェーニング(?.)との組み合わせ
・三項演算子・switch 文との使い分け
・フォームバリデーション等の実務パターン
スポンサーリンク

if 文の基本構文

if のみ

JavaScript
const age = 20;

if (age >= 18) {
  console.log("成人です");
}
// 条件が true なら {} 内が実行される

if … else

JavaScript
const age = 15;

if (age >= 18) {
  console.log("成人です");
} else {
  console.log("未成年です");
}
// 条件が false なら else ブロックが実行される

if … else if … else

JavaScript
const score = 75;

if (score >= 90) {
  console.log("A 評価");
} else if (score >= 70) {
  console.log("B 評価");
} else if (score >= 50) {
  console.log("C 評価");
} else {
  console.log("D 評価(不合格)");
}
// 上から順に評価され、最初に true になった分岐だけ実行される
else if は上から順に評価される
score = 75 の場合、score >= 90 は false → score >= 70 は true → 「B 評価」が出力されます。score >= 50 も true ですが、先に true になった分岐で確定するため評価されません

比較演算子

演算子 意味 結果
=== 厳密等価(型も値も一致) 1 === 1 true
!== 厳密不等価 1 !== “1” true
== 抽象等価(型変換あり) 1 == “1” true(型変換で一致)
!= 抽象不等価 1 != “1” false
> より大きい 5 > 3 true
>= 以上 5 >= 5 true
< より小さい 3 < 5 true
<= 以下 5 <= 5 true
JavaScript(== と === の違い)
// == は型変換してから比較(予期しない結果になりやすい)
console.log(1 == "1");     // true(文字列 "1" が数値に変換)
console.log(0 == false);   // true
console.log("" == false);  // true
console.log(null == undefined); // true

// === は型変換しない(推奨)
console.log(1 === "1");    // false(型が異なる)
console.log(0 === false);  // false
console.log("" === false); // false
常に === を使う
== は暗黙の型変換を行うため、予期しない true を返すことがあります。===(厳密等価)を使えば型も一致する場合のみ true になるため安全です。ESLint の eqeqeq ルールでも === の使用が推奨されています。

論理演算子(&&・||・!)

演算子 名前 動作
&& AND(かつ) 両方 true なら true age >= 18 && hasLicense
|| OR(または) どちらか true なら true isAdmin || isModerator
! NOT(否定) true/false を反転 !isLoggedIn
JavaScript(論理演算子の例)
const age = 25;
const hasLicense = true;

// AND: 両方の条件を満たす
if (age >= 18 && hasLicense) {
  console.log("運転できます");
}

// OR: いずれかの条件を満たす
const role = "moderator";
if (role === "admin" || role === "moderator") {
  console.log("管理画面にアクセスできます");
}

// NOT: 条件を反転
const isLoggedIn = false;
if (!isLoggedIn) {
  console.log("ログインしてください");
}
短絡評価(ショートサーキット)
&& は左辺が false なら右辺を評価しません。|| は左辺が true なら右辺を評価しません。これにより user && user.name のような安全なアクセスが可能です(user が null/undefined なら右辺を評価しない)。

truthy と falsy の判定

JavaScript の if 文は、条件が true / false だけでなく、あらゆる値を真偽値として評価します。

falsy な値(false として扱われる値)

備考
false Boolean そのもの
0 Number ゼロ
-0 Number マイナスゼロ
“”(空文字列) String 長さ 0 の文字列
null null 値がない
undefined undefined 未定義
NaN Number 非数

上記以外は全て truthy(true として扱われる)です。

JavaScript(truthy / falsy の例)
// falsy な値
if (0)         { /* 実行されない */ }
if ("")        { /* 実行されない */ }
if (null)      { /* 実行されない */ }
if (undefined) { /* 実行されない */ }
if (NaN)       { /* 実行されない */ }

// truthy な値(意外なもの)
if ("0")       { console.log("文字列の 0 は truthy"); }  // 実行される
if ([])        { console.log("空配列は truthy"); }       // 実行される
if ({})        { console.log("空オブジェクトは truthy"); } // 実行される
if ("false")   { console.log("文字列 false は truthy"); } // 実行される
“0” と [] と {} は truthy
文字列の "0"、空配列 []、空オブジェクト {}全て truthy です。if ("0") は true になります。数値のゼロチェックには if (value === 0)、空配列チェックには if (arr.length === 0) を使ってください。
JavaScript(truthy/falsy を活用した値チェック)
// 値が存在するかチェック(null / undefined / 空文字 / 0 を除外)
const name = getUserName();
if (name) {
  console.log("名前:", name);
} else {
  console.log("名前が未入力です");
}

// 0 も有効な値として扱いたい場合は != null を使う
const count = getCount(); // 0 が返る可能性がある
if (count != null) {
  console.log("カウント:", count); // 0 でも表示される
}

if 文のネストと回避テクニック

ネストが深い例(読みにくい)

NG: ネストが深い
// NG: ネストが 3 段 → 読みにくい
function processOrder(user, order) {
  if (user) {
    if (user.isActive) {
      if (order.amount > 0) {
        // ここまで辿り着くのが大変
        console.log("注文を処理します");
      }
    }
  }
}

早期リターン(ガード節)で解消

OK: 早期リターン
// OK: 異常系を先に弾く(ガード節)
function processOrder(user, order) {
  if (!user) return;
  if (!user.isActive) return;
  if (order.amount <= 0) return;

  // ここに到達 = 全条件クリア
  console.log("注文を処理します");
}
早期リターン(ガード節)でネストを減らす
「異常な条件を先に return で弾き、正常系だけ残す」書き方をガード節と呼びます。ネストが 2 段以上になったら早期リターンを検討してください。コードの可読性が大幅に向上します。

オプショナルチェーニング(?.)との組み合わせ

JavaScript
// user が null/undefined でもエラーにならない
const user = getUser(); // null かもしれない

// 従来の書き方
if (user && user.address && user.address.city) {
  console.log(user.address.city);
}

// オプショナルチェーニング(ES2020)
if (user?.address?.city) {
  console.log(user.address.city);
}

// Null 合体演算子(??)との組み合わせ
const city = user?.address?.city ?? "未設定";
console.log(city); // user が null なら "未設定"

if 文・三項演算子・switch 文の使い分け

構文 適するケース
if 文 複雑な条件分岐。副作用のある処理 if (age >= 18 && hasLicense) { … }
三項演算子 単純な 2 択で値を返す場合 const msg = age >= 18 ? “成人” : “未成年”
switch 文 1 つの値に対する多岐分岐(3 つ以上) switch (status) { case “active”: … }

三項演算子の詳細は「三項演算子の使い方」、switch 文の詳細は「switch 文で条件判定をスマートに行う」を参照してください。

実務パターン集

パターン(1): フォームバリデーション

JavaScript
function validateForm(name, email) {
  if (!name.trim()) {
    alert("名前を入力してください");
    return false;
  }
  if (!email.includes("@")) {
    alert("メールアドレスが不正です");
    return false;
  }
  return true;
}

パターン(2): API レスポンスの分岐

JavaScript
async function fetchUser(id) {
  const res = await fetch(`/api/users/${id}`);

  if (!res.ok) {
    if (res.status === 404) {
      console.error("ユーザーが見つかりません");
    } else if (res.status === 403) {
      console.error("アクセス権限がありません");
    } else {
      console.error("サーバーエラー:", res.status);
    }
    return null;
  }

  return await res.json();
}

パターン(3): 機能の有効/無効を切り替え

JavaScript
const isDebug = location.hostname === "localhost";

if (isDebug) {
  console.log("デバッグモード: ON");
  // 開発時のみ実行する処理
}

パターン(4): 配列・オブジェクトの存在チェック

JavaScript
// 配列が空でないかチェック
const items = getItems();
if (items && items.length > 0) {
  renderList(items);
} else {
  renderEmptyMessage();
}

// オブジェクトのプロパティ存在チェック
if ("name" in user) {
  console.log(user.name);
}

パターン(5): typeof による型チェック

JavaScript
// typeof でデータ型を安全にチェック
function greet(name) {
  if (typeof name !== "string") {
    throw new TypeError("name は文字列で指定してください");
  }
  console.log(`Hello, ${name}!`);
}

よくある間違い

間違い 正しい書き方 説明
if (x = 1) if (x === 1) = は代入。=== で比較する
if (x == null || x == undefined) if (x == null) == null は undefined も含むため 1 条件で十分
if (arr == []) if (arr.length === 0) [] は毎回新しいオブジェクト。参照比較では常に false
if (str == “”) if (str === “” || !str) 0 や false との混同を避けるため === を使う
= と === を間違えない
if (x = 1) は「x に 1 を代入」してから「1 は truthy なので true」になります。比較ではなく代入であり、常に true になるバグの原因です。ESLint の no-cond-assign ルールで検出できます。

よくある質問

Qif の条件に波括弧 {} は省略できますか?
A1 行だけの場合は省略可能ですが、省略しないことを推奨します。if (x) doSomething(); は動作しますが、後から処理を追加したときにバグの原因になります。常に { } を付ける習慣をつけてください。
Q== と === はどちらを使うべきですか?
A=== を常に使うのが推奨です。== は暗黙の型変換を行うため、0 == "" が true になるなど予期しない結果を返します。唯一の例外は value == null(null と undefined の両方をチェック)ですが、これも value === null || value === undefined と書く方が明示的です。
Qtruthy/falsy を使った判定は安全ですか?
A文字列や配列の「空でないか」のチェックには便利ですが、0 が有効な値の場合は注意が必要です。if (count) は count が 0 のとき false になります。0 も有効な値として扱いたい場合は if (count !== undefined)if (count != null) を使ってください。
Qelse if と else の違いは?
Aelse if は追加の条件を指定します。else はどの条件にも該当しなかった場合の処理です。else は省略可能で、必要なければ書かなくても構いません。
Qif 文の条件が長くなって読みにくいです
A条件を変数に抽出してください。
const isEligible = age >= 18 && hasLicense && !isSuspended;
if (isEligible) { ... }

変数名に「何の条件か」が表現され、可読性が大幅に向上します。
Qif 文と三項演算子はどう使い分けますか?
A値を返す場合は三項演算子、処理を実行する場合は if 文を使います。三項演算子の中で関数を呼んだり副作用のある処理を書くのは避けてください。詳細は「三項演算子の使い方」を参照。

まとめ

if 文の要点をまとめます。

やりたいこと 書き方
単純な条件分岐 if (condition) { … }
2 択の分岐 if (condition) { … } else { … }
3 つ以上の分岐 if … else if … else if … else
複数条件の AND if (a && b) { … }
複数条件の OR if (a || b) { … }
条件の否定 if (!condition) { … }
値の存在チェック if (value) { … }(truthy/falsy を活用)
null/undefined チェック if (value == null) { … } または if (value != null)
深いプロパティの安全なアクセス if (user?.address?.city) { … }
ネストの回避 早期リターン(ガード節): if (!x) return;

三項演算子は「三項演算子の使い方」、switch 文は「switch 文で条件判定をスマートに行う」も併せて参照してください。