はじめに

プログラミングにおいて、条件によって処理を分岐させることは基本中の基本です。JavaScriptでは、条件分岐を実現するために主にif文とswitch文が用意されています。

本記事では、以下の内容を初心者向けにわかりやすく解説します。

  • if文の基本構文: 単純なif文からelse if、ネストまで
  • switch文の基本構文: 複数の値に対する分岐処理
  • if文とswitch文の使い分け: どちらを選ぶべきかの判断基準
  • 実践的なテクニック: 早期リターンやガード節によるコードの改善
  • よくある間違いと注意点: 初心者が陥りやすいミスとその対策

if文の基本

if文は、指定した条件が真(truthy)である場合に、特定の処理を実行するための構文です。

基本構文

1
2
3
if (条件式) {
  // 条件が true のとき実行される処理
}

簡単な例

1
2
3
4
5
6
const age = 20;

if (age >= 18) {
  console.log("成人です");
}
// 出力: "成人です"

この例では、age >= 18という条件式がtrueと評価されるため、console.log("成人です")が実行されます。

条件式で使用される値について

JavaScriptでは、条件式の結果がブール値(trueまたはfalse)でなくても、自動的に真偽値として評価されます。これを「truthy」と「falsy」と呼びます。

falsyな値 説明
false ブール値のfalse
0-0 数値のゼロ
""(空文字列) 空の文字列
null null値
undefined undefined値
NaN Not a Number

上記以外のすべての値はtruthyとして扱われます。

1
2
3
4
5
6
7
8
const username = "";

if (username) {
  console.log(`ようこそ、${username}さん`);
} else {
  console.log("ユーザー名が入力されていません");
}
// 出力: "ユーザー名が入力されていません"

if…else文

条件がfalseの場合に別の処理を実行したい場合は、else節を追加します。

基本構文

1
2
3
4
5
if (条件式) {
  // 条件が true のとき実行される処理
} else {
  // 条件が false のとき実行される処理
}

例: 偶数・奇数の判定

1
2
3
4
5
6
7
8
const number = 7;

if (number % 2 === 0) {
  console.log(`${number}は偶数です`);
} else {
  console.log(`${number}は奇数です`);
}
// 出力: "7は奇数です"

else if文(複数条件の分岐)

3つ以上の条件で分岐する場合は、else ifを使用します。

基本構文

1
2
3
4
5
6
7
8
9
if (条件式1) {
  // 条件式1が true のとき
} else if (条件式2) {
  // 条件式1が false かつ 条件式2が true のとき
} else if (条件式3) {
  // 条件式1、2が false かつ 条件式3が true のとき
} else {
  // すべての条件が false のとき
}

例: 成績評価

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
const score = 85;
let grade;

if (score >= 90) {
  grade = "A";
} else if (score >= 80) {
  grade = "B";
} else if (score >= 70) {
  grade = "C";
} else if (score >= 60) {
  grade = "D";
} else {
  grade = "F";
}

console.log(`あなたの成績は${grade}です`);
// 出力: "あなたの成績はBです"

この例では、scoreが85なので、最初の条件score >= 90はfalse、次の条件score >= 80がtrueとなり、gradeに"B"が代入されます。

ネストしたif文

if文の中にさらにif文を記述することを「ネスト」と呼びます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
const isLoggedIn = true;
const isAdmin = true;

if (isLoggedIn) {
  if (isAdmin) {
    console.log("管理者ダッシュボードを表示");
  } else {
    console.log("ユーザーページを表示");
  }
} else {
  console.log("ログインページにリダイレクト");
}
// 出力: "管理者ダッシュボードを表示"

ただし、ネストが深くなるとコードの可読性が低下します。後述する「早期リターン」を活用して、ネストを避けることをおすすめします。

switch文の基本

switch文は、一つの式の値を複数のケースと照合し、一致したケースの処理を実行します。

基本構文

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
switch () {
  case 値1:
    // 式 === 値1 のとき実行される処理
    break;
  case 値2:
    // 式 === 値2 のとき実行される処理
    break;
  default:
    // どのcaseにも一致しないとき実行される処理
}

例: 曜日による処理の分岐

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
const dayOfWeek = "水曜日";

switch (dayOfWeek) {
  case "月曜日":
    console.log("週の始まりです。頑張りましょう!");
    break;
  case "水曜日":
    console.log("週の折り返しです!");
    break;
  case "金曜日":
    console.log("もうすぐ週末です!");
    break;
  case "土曜日":
  case "日曜日":
    console.log("週末です。ゆっくり休みましょう!");
    break;
  default:
    console.log("今日も一日頑張りましょう!");
}
// 出力: "週の折り返しです!"

switch文の重要なポイント

switch文を使う上で、以下の3つのポイントを必ず押さえておきましょう。

1. 厳密等価演算子(===)で比較される

switch文では、式とcase値の比較に厳密等価演算子(===)が使用されます。型が異なると一致しません。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
const value = "1";

switch (value) {
  case 1:
    console.log("数値の1");
    break;
  case "1":
    console.log("文字列の1");
    break;
}
// 出力: "文字列の1"

2. breakを忘れるとフォールスルーが発生する

breakを記述しないと、次のcaseの処理も続けて実行されます。これを「フォールスルー(fall-through)」と呼びます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
const fruit = "りんご";

switch (fruit) {
  case "りんご":
    console.log("りんごを選択");
    // breakがないので次のcaseも実行される
  case "みかん":
    console.log("みかんを選択");
    break;
  case "ぶどう":
    console.log("ぶどうを選択");
    break;
}
// 出力:
// "りんごを選択"
// "みかんを選択"

この挙動は意図的に利用することもできます(後述)。

3. defaultは省略可能だが推奨

default節は省略可能ですが、予期しない値が渡された場合の処理を記述しておくことで、バグの発見が容易になります。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
const status = "unknown";

switch (status) {
  case "success":
    console.log("成功");
    break;
  case "error":
    console.log("エラー");
    break;
  default:
    console.log(`未知のステータス: ${status}`);
}
// 出力: "未知のステータス: unknown"

フォールスルーの意図的な活用

複数のcaseで同じ処理を実行したい場合、フォールスルーを意図的に活用できます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
const month = 2;
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;
  case 12:
  case 1:
  case 2:
    season = "冬";
    break;
  default:
    season = "不明";
}

console.log(`${month}月は${season}です`);
// 出力: "2月は冬です"

case節でのスコープに関する注意

case節の中でletconstを使って変数を宣言する場合、ブロック({})で囲む必要があります。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
// エラーになる例
switch (action) {
  case "greet":
    const message = "こんにちは";  // ここで宣言
    console.log(message);
    break;
  case "farewell":
    const message = "さようなら";  // SyntaxError: 再宣言エラー
    console.log(message);
    break;
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
// 正しい書き方
switch (action) {
  case "greet": {
    const message = "こんにちは";
    console.log(message);
    break;
  }
  case "farewell": {
    const message = "さようなら";
    console.log(message);
    break;
  }
}

各case節をブロックで囲むことで、それぞれ独立したスコープを持つようになります。

if文とswitch文の使い分け

if文とswitch文は、どちらも条件分岐を実現しますが、それぞれ適した場面があります。

flowchart TD
    A[条件分岐が必要] --> B{条件の種類は?}
    B -->|単一の値との比較が複数| C[switch文を検討]
    B -->|範囲や複雑な条件| D[if文を使用]
    C --> E{値のパターンが3つ以上?}
    E -->|Yes| F[switch文を使用]
    E -->|No| G[if文でも十分]
    D --> H[if-else if-else を使用]

if文が適している場面

  • 範囲の比較: score >= 80のような範囲を指定する条件
  • 複数の条件の組み合わせ: &&||を使った複合条件
  • 真偽値の判定: isValidのようなフラグのチェック
  • 分岐が2〜3パターン程度: シンプルな二択や三択
1
2
3
4
5
6
7
8
// if文が適している例: 範囲の比較
if (temperature >= 30) {
  console.log("暑いです");
} else if (temperature >= 20) {
  console.log("快適です");
} else {
  console.log("寒いです");
}

switch文が適している場面

  • 特定の値との一致: ステータスコード、列挙型のような離散値
  • 分岐が多い: 4つ以上のパターンがある場合
  • 値に応じた明確な処理: メニュー選択やコマンド処理
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// switch文が適している例: HTTPステータスコード
switch (statusCode) {
  case 200:
    console.log("成功");
    break;
  case 400:
    console.log("不正なリクエスト");
    break;
  case 401:
    console.log("認証が必要");
    break;
  case 403:
    console.log("アクセス禁止");
    break;
  case 404:
    console.log("見つかりません");
    break;
  case 500:
    console.log("サーバーエラー");
    break;
  default:
    console.log(`ステータスコード: ${statusCode}`);
}

早期リターン(ガード節)によるリファクタリング

ネストが深いif文は、早期リターン(ガード節)を使ってフラットに書き換えることで可読性が向上します。

改善前: ネストが深い例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
function processOrder(order) {
  if (order) {
    if (order.items && order.items.length > 0) {
      if (order.paymentMethod) {
        // 実際の注文処理
        console.log("注文を処理します");
        return { success: true };
      } else {
        return { error: "支払い方法が選択されていません" };
      }
    } else {
      return { error: "カートが空です" };
    }
  } else {
    return { error: "注文情報がありません" };
  }
}

改善後: 早期リターンを使った例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
function processOrder(order) {
  if (!order) {
    return { error: "注文情報がありません" };
  }

  if (!order.items || order.items.length === 0) {
    return { error: "カートが空です" };
  }

  if (!order.paymentMethod) {
    return { error: "支払い方法が選択されていません" };
  }

  // 実際の注文処理
  console.log("注文を処理します");
  return { success: true };
}

早期リターンを使うと、異常系の処理を先に終わらせ、正常系の処理をメインのフローとして記述できます。これにより、コードの意図が明確になります。

三項演算子による簡潔な条件分岐

単純な二択の場合、三項演算子(条件 ? 真の値 : 偽の値)を使うと簡潔に書けます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
const age = 20;

// if文を使った場合
let status;
if (age >= 18) {
  status = "成人";
} else {
  status = "未成年";
}

// 三項演算子を使った場合
const status = age >= 18 ? "成人" : "未成年";

ただし、三項演算子のネストは可読性を著しく低下させるため、避けるべきです。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
// 避けるべき例: ネストした三項演算子
const result = score >= 90 ? "A" : score >= 80 ? "B" : score >= 70 ? "C" : "F";

// 推奨: if-else ifを使う
let result;
if (score >= 90) {
  result = "A";
} else if (score >= 80) {
  result = "B";
} else if (score >= 70) {
  result = "C";
} else {
  result = "F";
}

よくある間違いと注意点

1. 代入演算子(=)と等価演算子(==, ===)の混同

条件式で=を使うと、比較ではなく代入になってしまいます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
const x = 5;

// 間違い: 代入になってしまう
if (x = 10) {
  console.log("xは10です");  // 常に実行される
}

// 正しい: 比較演算子を使う
if (x === 10) {
  console.log("xは10です");
}

2. 型を意識しない比較

==(等価演算子)は型変換を行うため、意図しない結果になることがあります。

1
2
3
4
5
console.log(0 == "");       // true(両方falsyとして扱われる)
console.log(0 === "");      // false(型が異なる)

console.log(null == undefined);  // true
console.log(null === undefined); // false

基本的には===(厳密等価演算子)を使用することをおすすめします。

3. switch文でのbreak忘れ

意図しないフォールスルーを防ぐため、各caseの最後に必ずbreakを記述しましょう。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
switch (color) {
  case "赤":
    console.log("Red");
    break;  // 忘れずに!
  case "青":
    console.log("Blue");
    break;  // 忘れずに!
  default:
    console.log("Unknown");
}

実践的なサンプル: ユーザー権限チェック

最後に、実践的な例として、ユーザー権限に応じた画面表示を行う関数を紹介します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
function getAccessLevel(user) {
  // ガード節で異常系を先に処理
  if (!user) {
    return "guest";
  }

  if (!user.isVerified) {
    return "unverified";
  }

  // 権限レベルに応じた分岐
  switch (user.role) {
    case "admin":
      return "full_access";
    case "editor":
      return "edit_access";
    case "viewer":
      return "read_only";
    default:
      return "basic";
  }
}

// 使用例
const user1 = { isVerified: true, role: "editor" };
console.log(getAccessLevel(user1)); // "edit_access"

const user2 = { isVerified: false, role: "admin" };
console.log(getAccessLevel(user2)); // "unverified"

console.log(getAccessLevel(null));  // "guest"

この例では、早期リターンとswitch文を組み合わせることで、読みやすく保守しやすいコードを実現しています。

まとめ

JavaScriptの条件分岐について、if文とswitch文の基本から実践的な活用法まで解説しました。

項目 if文 switch文
主な用途 範囲比較、複合条件 特定値との一致
比較方法 任意の条件式 厳密等価(===)
可読性 分岐が少ないとき良い 分岐が多いとき良い

条件分岐を適切に使い分けることで、より読みやすく保守しやすいコードを書くことができます。また、早期リターンや三項演算子を活用して、ネストを減らし、コードの意図を明確にすることを心がけましょう。

参考リンク