JavaScriptの基礎 - 条件分岐

2026年2月19日 (木) 01:48時点におけるWiki (トーク | 投稿記録)による版 (ページの作成:「== 概要 == JavaScriptにおける条件分岐は、プログラムの実行フローを制御するための基本的な仕組みである。<br> 条件の真偽に応じて異なる処理を実行することで、複雑なロジックを表現できる。<br> <br> JavaScriptには、条件分岐を実現するための主要な構文として、<code>if</code> / <code>else if</code> / <code>else</code>文、三項演算子 (条件演算子)、<code>switch</code>…」)
(差分) ← 古い版 | 最新版 (差分) | 新しい版 → (差分)
📢 Webサイト閉鎖と移転のお知らせ
このWebサイトは2026年9月に閉鎖いたします。
新しい記事は移転先で追加しております。(旧サイトでは記事を追加しておりません)

概要

JavaScriptにおける条件分岐は、プログラムの実行フローを制御するための基本的な仕組みである。
条件の真偽に応じて異なる処理を実行することで、複雑なロジックを表現できる。

JavaScriptには、条件分岐を実現するための主要な構文として、if / else if / else文、三項演算子 (条件演算子)、switch文の3つが存在する。
それぞれに適切な使用場面があり、状況に応じて使い分けることが重要である。

また、JavaScriptでは条件式においてあらゆる値が真偽値として評価される。
この特性を、Truthy / Falsy と呼ぶ。

Falsyな値は、false0-00n""nullundefinedNaN の8つに限定されており、
それ以外の値は全てTruthyとして扱われる。



if / else if / else

if 文は、最も基本的な条件分岐構文である。
条件式がTruthyと評価された場合にブロック内の処理を実行し、Falsyの場合は else 節の処理を実行する。

基本構文

if 文の基本的な構文を以下に示す。

 if (condition) {
    // condition が Truthy の場合に実行される
    statement1;
 }
 else if (condition2) {
    // condition2 が Truthy の場合に実行される
    statement2;
 }
 else {
    // いずれの条件も Falsy の場合に実行される
    statement3;
 }


使用例を以下に示す。

 const score = 75;
 
 if (score >= 90) {
    console.log("優");
 }
 else if (score >= 80) {
    console.log("良");
 }
 else if (score >= 70) {
    console.log("可");
 }
 else {
    console.log("不可");
 }
 // "可"


else if は任意の数を連鎖できるが、条件は上から順に評価される。
最初にTruthyとなった節のブロックが実行され、以降の条件は評価されない。

ブロックと中括弧

if 文では、中括弧 {} を省略して1行で記述することも文法上は可能である。
しかし、中括弧を省略すると、dangling else問題が発生するリスクがあり、コードの可読性が低下する。

 // 中括弧を省略した例 (非推奨)
 if (condition) doSomething();
 
 // ネストした場合に問題が発生しやすい
 if (a)
    if (b)
       console.log("a and b");
 else
    console.log("?");  // このelseはどのifに属するか? (内側のif)


 // 中括弧を常に使用する (推奨)
 if (a) {
    if (b) {
       console.log("a and b");
    }
 }
 else {
    console.log("not a");  // 意図が明確になる
 }


中括弧を常に使用することにより、コードの意図が明確になり、後から文を追加した際のバグを防ぐことができる。

ネストしたif文

if 文はネストして記述できるが、ネストが深くなるとコードの可読性が著しく低下する。

 // ネストが深い例 (可読性が低い)
 function processUser(user) {
    if (user) {
       if (user.isActive) {
          if (user.isVerified) {
             console.log("ユーザー処理を続行");
             // 本来の処理
          }
       }
    }
 }


このような場合は、ガード節 (早期リターン) パターンを用いてネストを解消することが推奨される。

 // ガード節を使用した例 (可読性が高い)
 function processUser(user) {
    if (!user) return;
    if (!user.isActive) return;
    if (!user.isVerified) return;
 
    console.log("ユーザ処理を続行");
    // 本来の処理
 }


ガード節パターンでは、無効な条件を先頭で早期に除外することで、メインロジックをフラットな構造で記述できる。

条件式のパターン

if 文の条件式には、様々なパターンが使用できる。

  • 等値比較
    値の一致を確認する際は、型変換を行わない厳密等価演算子 (===) を使用することが推奨される。
     const status = "active";
     
     if (status === "active") {
        console.log("アクティブなユーザー");
     }
     
     // == は型変換を行うため予期しない動作になる可能性がある (非推奨)
     if (status == "active") { }
    

  • 範囲チェック
    数値が特定の範囲内にあるかどうかを確認するパターンである。
     const age = 25;
     
     if (age >= 18 && age < 65) {
        console.log("成人 (就労年齢)");
     }
    

  • 存在確認
    オブジェクトのプロパティや変数の値が存在するかどうかを確認するパターンである。
     const user = { name: "Alice", profile: { bio: "Developer" } };
     
     if (user.profile) {
        console.log(user.profile.bio);
     }
     
     // null または undefined の両方を除外する厳密な確認
     if (user.profile !== null && user.profile !== undefined) {
        console.log(user.profile.bio);
     }
    

  • typeof演算子を使用した型チェック
     function greet(value) {
        if (typeof value === "string") {
           console.log("こんにちは、" + value + "さん");
        }
        else if (typeof value === "number") {
           console.log("番号: " + value);
        }
        else {
           console.log("不明な値: " + value);
        }
     }
     
     greet("Alice"); // "こんにちは、Aliceさん"
     greet(42);      // "番号: 42"
    



三項演算子 (条件演算子)

三項演算子 (条件演算子) は、JavaScriptで唯一の3つのオペランドを取る演算子である。
簡潔な条件分岐を式として記述でき、変数への代入や関数の引数として使用できる。

基本構文

三項演算子の構文は以下の通りである。

 condition ? exprIfTrue : exprIfFalse


condition がTruthyの場合は exprIfTrue が評価されて返され、Falsyの場合は exprIfFalse が評価されて返される。

使用例を以下に示す。

 const age = 25;
 const beverage = age >= 21 ? "Beer" : "Juice";
 console.log(beverage);  // "Beer"
 
 // 関数の引数での使用
 console.log(age >= 20 ? "成人" : "未成年");
 
 // テンプレートリテラル内での使用
 const isLoggedIn = true;
 const greeting = `ようこそ、${isLoggedIn ? "ユーザー" : "ゲスト"}さん`;
 console.log(greeting);  // "ようこそ、ユーザーさん"


if文との使い分け

三項演算子と if 文は、使用場面が異なる。

  • 三項演算子が適している場合
    • 単純な値の決定 (2つの選択肢から1つを選ぶ)
    • 変数への代入
    • 式として評価される文脈 (テンプレートリテラル、JSXなど)

  • if 文が適している場合
    • 複数行にわたる処理
    • 副作用を伴う処理 (関数呼び出し、ログ出力等)
    • 複雑な条件ロジック


 // 三項演算子が適切な例: 値の決定
 const label = isActive ? "有効" : "無効";
 const discount = isMember ? price * 0.8 : price;
 
 // if文が適切な例: 複数行の処理
 if (isActive) {
    user.activate();
    sendWelcomeEmail(user);
    console.log("アクティベート完了");
 }
 else {
    user.deactivate();
    console.log("無効化完了");
 }


ネストした三項演算子

三項演算子はネストして連鎖させることが可能であるが、一般的に非推奨である。

 // ネストした三項演算子 (非推奨: 可読性が低い)
 const score = 75;
 const grade = score >= 90
    ? "優"
    : score >= 80
    ? "良"
    : score >= 70
    ? "可"
    : "不可";


このような複数の条件分岐が必要な場合は、if / else if 文を使用することが推奨される。

 // if / else if を使用した例 (推奨: 可読性が高い)
 let grade;
 if (score >= 90) {
    grade = "優";
 }
 else if (score >= 80) {
    grade = "良";
 }
 else if (score >= 70) {
    grade = "可";
 }
 else {
    grade = "不可";
 }



switch文

switch 文は、1つの式を複数の値と比較する際に用いる条件分岐構文である。
複数の選択肢がある場合に、if / else if の連鎖よりも可読性が高くなることがある。

基本構文

switch 文の基本的な構文を以下に示す。

 switch (expression) {
    case value1:
       // expression === value1 の場合に実行される
       statements;
       break;
    case value2:
       // expression === value2 の場合に実行される
       statements;
       break;
    default:
       // いずれのcaseにも一致しない場合に実行される
       statements;
 }


switch 文は、expressionの値を各caseの値と厳密等価演算子 (===) で比較する。
default 節は省略可能であるが、予期しない値への対処のため記述することが推奨される。

使用例を以下に示す。

 const day = "Monday";
 
 switch (day) {
    case "Monday":
       console.log("月曜日: 週の始まり");
       break;
    case "Friday":
       console.log("金曜日: 週の終わり");
       break;
    case "Saturday":
    case "Sunday":
       console.log("週末");
       break;
    default:
       console.log("平日");
 }
 // "月曜日: 週の始まり"


breakとフォールスルー

switch 文において、break文はブロックの実行を終了して switch 文から抜け出す役割を担う。

break 文を省略すると、フォールスルー (fall-through) が発生し、次のcaseの処理も続けて実行される。

 // フォールスルーが発生する例
 const num = 1;
 
 switch (num) {
    case 1:
       console.log("1");  // 実行される
    case 2:
       console.log("2");  // break がないため続けて実行される
    case 3:
       console.log("3");  // break がないため続けて実行される
       break;
    case 4:
       console.log("4");  // 実行されない
 }
 // "1", "2", "3" が全て出力される


フォールスルーは通常バグの原因となるため、意図的に使用する場合はコメントで明示することが推奨される。

 // 意図的なフォールスルー (コメントで明示する)
 switch (command) {
    case "save":
    case "write":
       // "save" と "write" で同じ処理を行う (意図的なフォールスルー)
       saveToFile();
       break;
    case "quit":
    case "exit":
       // "quit" と "exit" で同じ処理を行う (意図的なフォールスルー)
       closeApplication();
       break;
 }


switch文の応用

switch 文には、基本的な使い方以外にもいくつかの応用パターンが存在する。

  • グルーピング
    複数の case で同じ処理を実行したい場合、case を連続して並べることでグルーピングできる。
     const month = 4;
     let season;
     
     switch (month) {
        case 3:
        case 4:
        case 5:
           season = "春";
           break;
        case 6:
        case 7:
        case 8:
           season = "夏";
           break;
        case 9:
        case 10:
        case 11:
           season = "秋";
           break;
        default:
           season = "冬";
     }
     
     console.log(season);  // "春"
    

  • switch(true) パターン
    switch文の式に true を指定し、各 case で条件式を記述するパターンである。
    複雑な条件式を switch 構造で整理したい場合に有用である。
     const score = 75;
     let grade;
     
     switch (true) {
        case score >= 90:
           grade = "優";
           break;
        case score >= 80:
           grade = "良";
           break;
        case score >= 70:
           grade = "可";
           break;
        default:
           grade = "不可";
     }
     
     console.log(grade);  // "可"
    

  • ブロックスコープ
    case 節内で let / const を使用する場合、同じ switchブロック内で変数名が衝突する可能性がある。
    この問題を回避するには、case 節を中括弧で囲んで独立したブロックスコープを作成する。
     switch (action) {
        case "create": {
           const id = generateId();     // このブロック内のみで有効
           const item = createItem(id);
           console.log(item);
           break;
        }
        case "delete": {
           const id = getSelectedId();  // 別ブロックなので同名でもOK
           deleteItem(id);
           break;
        }
     }
    


if文との使い分け

switch 文 と if 文はそれぞれ異なる場面に適している。

下表に比較を示す。

if文とswitch文の比較
観点 if文 switch文
比較の種類 あらゆる条件式 (範囲比較、関数の戻り値など) 1つの式を複数の値と比較
比較演算子 ===、!==、<、>、&&、|| 等、自由に指定 === のみ (厳密等価)
型の比較 あらゆる型の条件式 プリミティブ値との厳密等価
可読性 条件が少ない場合や複雑な条件式に適する 同一の式を複数の値と比較する場合に適する
フォールスルー なし あり (breakを省略すると発生)
デフォルト処理 else節 default節
適した場面 範囲チェック、複雑なロジック、型チェック 列挙型、固定の文字列・数値との比較


 // switch文が適した例: 固定の文字列との比較
 switch (statusCode) {
    case 200: console.log("OK"); break;
    case 404: console.log("Not Found"); break;
    case 500: console.log("Internal Server Error"); break;
    default:  console.log("その他");
 }
 
 // if文が適した例: 範囲比較
 if (temperature >= 35) {
    console.log("猛暑");
 }
 else if (temperature >= 25) {
    console.log("夏日");
 }
 else if (temperature >= 0) {
    console.log("通常");
 }
 else {
    console.log("氷点下");
 }



Truthy / Falsy

JavaScriptでは、if 文等の条件式においてあらゆる値が自動的に真偽値へ変換される。
この時、false と評価される値をFalsy、true と評価される値をTruthyと呼ぶ。

Falsy値一覧

JavaScriptにおけるFalsy値は以下の8つのみである。
これら以外の全ての値は、Truthyとなる。

Falsy値一覧
説明
false Boolean ブール値の false
0 Number 数値のゼロ
-0 Number 負のゼロ
0n BigInt BigInt のゼロ
"" String 空文字列 (長さ0の文字列)
null Null 値の意図的な欠落
undefined Undefined 未定義 (値が代入されていない)
NaN Number 非数値 (Not a Number)


 // 各Falsy値の確認
 if (false)     { }  // 実行されない
 if (0)         { }  // 実行されない
 if (-0)        { }  // 実行されない
 if (0n)        { }  // 実行されない
 if ("")        { }  // 実行されない
 if (null)      { }  // 実行されない
 if (undefined) { }  // 実行されない
 if (NaN)       { }  // 実行されない
 
 // Boolean()による明示的な変換で確認
 console.log(Boolean(false));     // false
 console.log(Boolean(0));         // false
 console.log(Boolean(""));        // false
 console.log(Boolean(null));      // false
 console.log(Boolean(undefined)); // false
 console.log(Boolean(NaN));       // false


注意が必要なTruthy値

一見、Falsyのように思えるが、実際にはTruthyと評価される値が存在する。
これらはバグの原因になりやすいため、特に注意が必要である。

  • "0" (文字列のゼロ)
    数値の 0 はFalsyだが、文字列 "0" は空文字列ではないためTruthyである。
  • "false" (文字列のfalse)
    ブール値の false はFalsyだが、文字列 "false" はTruthyである。
  • [] (空の配列)
    空の配列はオブジェクトであるため、Truthyである。
  • {} (空のオブジェクト)
    空のオブジェクトもTruthyである。


 // 注意が必要なTruthy値
 console.log(Boolean("0"));     // true (文字列 "0" は Truthy)
 console.log(Boolean("false")); // true (文字列 "false" は Truthy)
 console.log(Boolean([]));      // true (空配列は Truthy)
 console.log(Boolean({}));      // true (空オブジェクトは Truthy)
 
 // よくある誤り
 const value = "0";
 if (value) {
    console.log("Truthy");  // こちらが実行される
 }
 else {
    console.log("Falsy");   // 実行されない
 }
 
 // 空配列の確認は、lengthプロパティを使用する
 const arr = [];
 if (arr.length === 0) {
    console.log("空の配列");  // 正しいチェック方法
 }


条件分岐での活用

Truthy / Falsyの特性を利用することで、簡潔な条件分岐を記述できる。

 const user = getUserFromDB();
 
 // userがnullまたはundefinedでないかを確認
 if (user) {
    console.log("ユーザーが存在する: " + user.name);
 }
 
 // 文字列の存在確認
 const message = getMessage();
 if (message) {
    displayMessage(message);
 }
 
 // 配列の存在および要素確認 (要素数も考慮する場合は、lengthを使用)
 const items = getItems();
 if (items && items.length > 0) {
    renderList(items);
 }


暗黙の型変換に関する注意点

条件式で暗黙の型変換が行われることにより、意図しない動作が生じる場合がある。
明示的な比較を記述することで、こうした問題を回避できる。

 // 暗黙の型変換による問題
 function processCount(count) {
    // count が 0 の場合、Falsy と判定されて処理がスキップされる
    if (count) {
       console.log("件数: " + count);
    }
 }
 
 processCount(0);  // 何も出力されない (意図しない動作)
 
 // 明示的な比較で解決する
 function processCountFixed(count) {
    if (count !== null && count !== undefined) {
       console.log("件数: " + count);
    }
 }
 
 processCountFixed(0);  // "件数: 0" (正しく動作する)


 // 数値の存在確認には、typeofを使用する
 function isValidNumber(value) {
    return typeof value === "number" && !isNaN(value);
 }
 
 console.log(isValidNumber(0));         // true (0 は有効な数値)
 console.log(isValidNumber(null));      // false
 console.log(isValidNumber(undefined)); // false
 console.log(isValidNumber(NaN));       // false


nullundefined のみを除外したい場合は、Null合体演算子 (??) の使用も検討する。
??nullundefined のみをFalsyとして扱うため、0"" が有効な値として扱われる。


実用的な条件分岐パターン

実際の開発でよく使用される条件分岐のパターンを以下に示す。

ガード節 (早期リターン)

ガード節 (Guard Clause) は、関数の先頭で無効な条件を早期に除外するパターンである。
ネストを浅く保ち、ソースコードの可読性を向上させることができる。

 // ネストが深い例 (避けるべきパターン)
 function sendEmail(user) {
    if (user) {
       if (user.email) {
          if (user.isSubscribed) {
             if (user.isVerified) {
                // メール送信処理
                mailer.send(user.email, "Welcome!");
             }
          }
       }
    }
 }


 // ガード節を使用した例 (推奨パターン)
 function sendEmail(user) {
    if (!user) return;
    if (!user.email) return;
    if (!user.isSubscribed) return;
    if (!user.isVerified) return;
 
    // 全ての条件を満たした場合のメイン処理
    mailer.send(user.email, "Welcome!");
 }


ガード節パターンのメリットを以下に示す。

  • ネストが浅くなりコードが読みやすくなる。
  • 各条件の意図が明確になる。
  • メインロジックが最後にフラットな形で記述される。
  • 単体試験が書きやすくなる。


入力検証パターンにガード節を適用した例を以下に示す。

 function createUser(name, age, email) {
    // 入力検証 (ガード節)
    if (typeof name !== "string" || name.trim() === "") {
       throw new Error("名前は必須です");
    }
 
    if (typeof age !== "number" || age < 0 || age > 150) {
       throw new Error("年齢が無効です");
    }
 
    if (typeof email !== "string" || !email.includes("@")) {
       throw new Error("メールアドレスが無効です");
    }
 
    // 検証を通過した場合のメイン処理
    return { name: name.trim(), age, email };
 }


オブジェクトルックアップ

オブジェクトルックアップは、switch 文の代替として使用できるパターンである。
キーと値のマッピングをオブジェクトとして定義し、動的にアクセスすることで条件分岐を簡潔に表現できる。

 // switch文を使用した場合
 function getStatusColor(status) {
    switch (status) {
       case "success": return "green";
       case "warning": return "orange";
       case "error":   return "red";
       case "info":    return "blue";
       default:        return "gray";
    }
 }


 // オブジェクトルックアップを使用した場合
 const statusColors = {
    success: "green",
    warning: "orange",
    error:   "red",
    info:    "blue",
 };
 
 function getStatusColor(status) {
    return statusColors[status] ?? "gray";
 }
 
 console.log(getStatusColor("success")); // "green"
 console.log(getStatusColor("unknown")); // "gray"


関数をオブジェクトの値として格納することで、より複雑な処理にも対応できる。

 // 関数をオブジェクトの値として格納するパターン
 const actions = {
    increment: (count) => count + 1,
    decrement: (count) => count - 1,
    reset:     (_)     => 0,
 };
 
 function applyAction(action, count) {
    const fn = actions[action];
    if (!fn) {
       throw new Error("不明なアクション: " + action);
    }
    return fn(count);
 }
 
 console.log(applyAction("increment", 5)); // 6
 console.log(applyAction("decrement", 5)); // 4
 console.log(applyAction("reset", 5));     // 0


オブジェクトルックアップパターンのメリットを以下に示す。

  • ソースコードが簡潔になる。
  • 新しい選択肢の追加がオブジェクトへの1行追加で済む。
  • オブジェクト自体を外部から注入したり動的に変更することができる。
  • フォールスルーの心配がない。



関連情報