JavaScript 入門

JavaScript switch 文

switch文は、JavaScriptにおける強力なコントロールフローツールの一つです。単一のエクスプレッション(式)の値に基づいて、複数の条件分岐を構造化された方法で処理することができます。

if...else if...else 文でも同様の効果を得ることは可能ですが、処理すべき値が大量にある場合、switch文の方がより可読性が高く、メンテナンスしやすいソリューションを提供できます。エクスプレッションの値がどの case(ケース) と一致するかに応じて、異なるコードブロックを実行させることが可能です。

1. switch文の構文を理解する

switch文は switch キーワードから始まり、その後に括弧内のエクスプレッションが続きます。このエクスプレッションは一度だけ計算され、その結果がswitchブロック内の各 case の値と比較されます。

switch (expression) {
  case value1:
    // expression === value1 の場合、ここを実行
    break;
  case value2:
    // expression === value2 の場合、ここを実行
    break;
  // ... さらなるケース
  default:
    // どの case にも一致しない場合、ここを実行
}
  • switch (expression): switchキーワードで文を開始し、エクスプレッションを評価します。結果は各 case の値と比較されます。
  • case value1:: 各 case はエクスプレッションと比較される具体的な値を表します。エクスプレッションが 厳密等価 (===) で value1 と等しい場合、その直後のコードが実行されます。
  • break;: break 文は極めて重要です。これはswitch文を終了させ、コードが次の case に「フォールスルー(貫通)」するのを防ぎます。breakがないと、値が一致するかどうかにかかわらず、プログラムは次の case のコードを実行し続けてしまいます。
  • default:: default(デフォルト)はオプションです。どの case にも一致しない場合に実行されるコードを指定します。予期しない値や無効な値を処理するために、default を含めておくのは良い習慣です。

2. break文の重要性

break 文は、switch文を単なる if 文の羅列と区別する鍵となります。breakがないと、コードの実行は次の case へと「貫通」してしまいます。これは予期しない挙動やバグの原因となります。

2.1 示例:breakがない場合(誤った例)

let day = 3;
let dayName = "";

switch (day) {
  case 1:
    dayName = "月曜日";
  case 2:
    dayName = "火曜日";
  case 3:
    dayName = "水曜日";
  case 4:
    dayName = "木曜日";
  case 5:
    dayName = "金曜日";
  case 6:
    dayName = "土曜日";
  case 7:
    dayName = "日曜日";
  default:
    dayName = "無効な日付";
}

console.log(dayName); // 出力: 無効な日付

この例では、break文がないため、コードは case 3 から開始された後、そのまま下のすべてのケースを通り抜け、最終的に default の「無効な日付」が代入されてしまいます。

2.2 示例:breakを使用した場合(正しい例)

let day = 3;
let dayName = "";

switch (day) {
  case 1:
    dayName = "月曜日";
    break;
  case 2:
    dayName = "火曜日";
    break;
  case 3:
    dayName = "水曜日";
    break;
  case 4:
    dayName = "木曜日";
    break;
  case 5:
    dayName = "金曜日";
    break;
  case 6:
    dayName = "土曜日";
    break;
  case 7:
    dayName = "日曜日";
    break;
  default:
    dayName = "無効な日付";
}

console.log(dayName); // 出力: 水曜日

break文があることで、day の値と一致した case だけが実行され、正しい結果が得られます。

3. defaultケース

default ケースは、どの case にも一致しなかった時に使用される「バックアップオプション」を提供します。通常は switch ブロックの最後に置かれますが、技術的にはどこに置いても構いません。ただし、最後に置かない場合は、そこでも break 文が必要になります。

3.1 示例:defaultの使用

let grade = "Z";
let feedback = "";

switch (grade) {
  case "A":
    feedback = "素晴らしい!";
    break;
  case "B":
    feedback = "よくできました!";
    break;
  case "C":
    feedback = "その調子!";
    break;
  case "D":
    feedback = "もう少し頑張りましょう。";
    break;
  case "F":
    feedback = "不合格です。";
    break;
  default:
    feedback = "無効なランクです。";
}

console.log(feedback); // 出力: 無効なランクです。

grade が "Z" であり、どの case にも該当しないため、default ブランチが実行されます。

4. switch文で異なるデータ型を使用する

switch文は、数値、文字列、ブーリアンなど、さまざまなデータ型に使用できます。ただし、エクスプレッションと case 値の比較は厳密等価 (===) で行われることを忘れないでください。つまり、データ型が完全に一致している必要があります。

4.1 文字列の例:

let fruit = "apple";

switch (fruit) {
  case "banana":
    console.log("私はバナナです。");
    break;
  case "apple":
    console.log("私はリンゴです。");
    break;
  case "orange":
    console.log("私はオレンジです。");
    break;
  default:
    console.log("そのフルーツは知りません。");
}
// 出力: 私はリンゴです。

4.2 数値の例:

let age = 25;

switch (age) {
  case 18:
    console.log("18歳ですね。");
    break;
  case 21:
    console.log("21歳ですね。");
    break;
  case 25:
    console.log("25歳ですね。");
    break;
  default:
    console.log("その他の年齢です。");
}
// 出力: 25歳ですね。

5. ケースの統合(グループ化)

複数の case 値に対して同じコードを実行したい場合があります。その場合、case をまとめて記述し、最後の case まで break を省略することでグループ化できます。

5.1 ケースのグループ化の例:

let day = 6;
let dayType = "";

switch (day) {
  case 1:
  case 2:
  case 3:
  case 4:
  case 5:
    dayType = "平日";
    break;
  case 6:
  case 7:
    dayType = "週末";
    break;
  default:
    dayType = "無効な日付";
}

console.log(dayType); // 出力: 週末

この例では、day が 1, 2, 3, 4, 5 のいずれかであれば、dayType = "平日"; まで貫通し、そこで break されます。6 または 7 の場合は「週末」になります。

6. switch vs. if...else if...else

両者はどちらも多重分岐に使用できますが、いくつかの重要な違いがあります:

特徴switch文if...else if...else文
可読性単一エクスプレッションの多くの離散値を扱う際に高い。複雑な条件や範囲を扱う際に適している。
条件の複雑さ単一の値を定数と比較するのに最適。数値の範囲や論理演算を組み合わせた複雑な条件が可能。
比較方法厳密等価 (===) のみ。任意の比較演算子(>, <, == など)が使用可能。
フォールスルーメリット(グループ化)にもデメリット(バグ)にもなる。存在しない。

6.1 if...else if...else を使うべき例(範囲の処理):

let temperature = 25;

if (temperature < 0) {
  console.log("氷点下");
} else if (temperature < 10) {
  console.log("非常に寒い");
} else if (temperature < 20) {
  console.log("寒い");
} else if (temperature < 30) {
  console.log("適温");
} else {
  console.log("暑い");
}
// 出力: 適温

数値の「範囲」を扱うのは switch 文が苦手(直接的には不可能)な領域であり、このような場合は if...else が適しています。

7. 実戦練習:シンプルな計算機を構築する

ユーザーの入力に基づいて基本的な算術演算を行うシンプルな計算機を構築してみましょう。

let num1 = 10;
let num2 = 5;
let operator = "+"; // 使用可能な値: "+", "-", "*", "/"
let result;

switch (operator) {
  case "+":
    result = num1 + num2;
    break;
  case "-":
    result = num1 - num2;
    break;
  case "*":
    result = num1 * num2;
    break;
  case "/":
    if (num2 === 0) {
      result = "0による除算エラー!";
    } else {
      result = num1 / num2;
    }
    break;
  default:
    result = "無効な演算子です";
}

console.log(`${num1} ${operator} ${num2} = ${result}`); 
// 出力: 10 + 5 = 15