2.

JavaScript switch文の使い方|break・default・フォールスルー

編集
この記事の要点
  • switch (式) { case 値: ... break; default: ... } で多分岐を表現
  • 比較は ===(厳密比較)。数値文字列と数値は区別される
  • break を忘れると次の case まで実行が続く(フォールスルー)
  • default はどの case にも当てはまらないときに実行。位置は最後でも途中でも可
  • 値の連続マッチ・範囲判定・オブジェクトリテラルマップなど、用途別の代替パターンも覚えておくとよい

switch 文とは

JavaScript の switch 文は、1 つの式を複数の値と順に比較して、合致した case ブロックを実行する分岐構文です。if / else if の連鎖を整理して書き直したいときに便利です。

基本構文

switch (式) {
  case 値1:
    // 式 === 値1 のときに実行
    break;
  case 値2:
    // 式 === 値2 のときに実行
    break;
  ...
  default:
    // どの case にも合致しないときに実行
}

基本例

const val = 2;

switch (val) {
  case 1:
    console.log('val = 1');
    break;
  case 2:
    console.log('val = 2');
    break;
  case 3:
    console.log('val = 3');
    break;
  default:
    console.log('It does not apply to any');
}
// 出力: val = 2

break の重要性

break を書き忘れると、合致した case の次の case も続けて実行されます(フォールスルー)。多くの場合バグの原因になるので、原則 break を必ず付けるルールにしておくと安全です。

const val = 1;

switch (val) {
  case 1:
    console.log('val = 1');
    // break なし
  case 2:
    console.log('val = 2');  // ← これも実行される
    break;
  default:
    console.log('default');
}
// 出力:
// val = 1
// val = 2

意図的なフォールスルー(複数値で同じ処理)

同じ処理を複数の値に割り当てたい場合、あえて break を省略してフォールスルーさせるのが定石です。

function dayType(day) {
  switch (day) {
    case 'Sat':
    case 'Sun':
      return 'Weekend';
    case 'Mon':
    case 'Tue':
    case 'Wed':
    case 'Thu':
    case 'Fri':
      return 'Weekday';
    default:
      return 'Unknown';
  }
}

dayType('Sat');  // 'Weekend'
dayType('Mon');  // 'Weekday'

default の位置

default は最後に書くのが慣例ですが、文法的にはどこに書いても動作します。途中に書く場合は break を意識する必要があります。

switch (n) {
  case 1:
    console.log('one');
    break;
  default:
    console.log('other');
    break;
  case 2:
    console.log('two');
    break;
}

比較は厳密等価(===)

switch の比較演算子は === です。型変換は行われないので、文字列と数値は区別されます。

const n = 1;

switch (n) {
  case '1':              // ← 文字列の '1' なのでマッチしない
    console.log('string one');
    break;
  case 1:
    console.log('number one'); // こちらにマッチ
    break;
}

範囲判定や条件式を書きたい場合

switch は値の一致比較しかできません。範囲条件を書きたいときは、式に true を渡して、各 case に条件式を書くテクニックがあります。

const score = 75;

switch (true) {
  case score >= 90:
    console.log('A');
    break;
  case score >= 75:
    console.log('B');
    break;
  case score >= 60:
    console.log('C');
    break;
  default:
    console.log('D');
}
// 出力: B

ただしこの書き方は読みにくいので、素直に if / else if の方が好まれることも多いです。チームのルールに合わせましょう。

case 内のブロックスコープ

case 内で let / const を使うときは、変数宣言の重複を避けるため { } でブロック化するのが定石です。

switch (action.type) {
  case 'ADD': {
    const newItem = { id: Date.now(), text: action.text };
    return [...state, newItem];
  }
  case 'REMOVE': {
    const newState = state.filter(x => x.id !== action.id);
    return newState;
  }
  default:
    return state;
}

switch 文 vs オブジェクトリテラル(マッピング)

「値 → 値」のシンプルな対応関係は、オブジェクトリテラルで書く方が読みやすいことも多いです。

// switch 版
function statusLabel(code) {
  switch (code) {
    case 200: return 'OK';
    case 404: return 'Not Found';
    case 500: return 'Server Error';
    default:  return 'Unknown';
  }
}

// オブジェクト版(フラットで宣言的)
const labels = {
  200: 'OK',
  404: 'Not Found',
  500: 'Server Error',
};
function statusLabel(code) {
  return labels[code] ?? 'Unknown';
}

switch 文 vs if 文の使い分け

シーン適切な構文
1 つの値を多数の定数と比較switch
条件が範囲・複数式の組み合わせif / else if
厳密等価で十分switch
値→値のマッピングオブジェクトリテラル / Map
列挙型風の分岐switch(TypeScript なら exhaustive チェック)

TypeScript での網羅性チェック

TypeScript なら never 型を使って「全 case を網羅したか」を型レベルで保証できます。

type Direction = 'up' | 'down' | 'left' | 'right';

function move(dir: Direction): void {
  switch (dir) {
    case 'up':    return ...;
    case 'down':  return ...;
    case 'left':  return ...;
    case 'right': return ...;
    default: {
      const _exhaustive: never = dir;  // 新しい値を増やすとここで型エラー
      throw new Error(`Unknown: ${dir}`);
    }
  }
}

よくあるトラブル

症状原因と対処
意図せず複数の case が実行されるbreak 忘れ。lint ルール no-fallthrough で防げる
文字列の数値とマッチしない厳密比較。Number(value) で揃える
case 内で同名の let が重複エラーcase ごとに { } でブロック化する
default に来ないcase の値の型・空白・大文字小文字を確認
switch が長すぎて読めないオブジェクトリテラル / Map / 関数テーブルにリファクタリング

関連

  • 条件文 — 親カテゴリ
  • if / else if / else — 条件分岐の基本
  • 三項演算子(?:) — 短い分岐
  • Map — 厳密な値-値マッピング
  • TypeScript never — 網羅性チェック
編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. if文
  2. switch

最近更新/作成されたページ