JavaScript | break文とcontinue文でラベルを指定する

JavaScript JavaScript
スポンサーリンク

JavaScript のラベル付き break / continue を初心者向けに

「なんでここでループが止まるんだろう?」——ネストしたループで迷子になりがちなところを、例題でスッキリさせます。まずは基本から、少しずつステップアップしましょう。


ループと break / continue の基本

  • ループの役割: 同じ処理を何回も繰り返すための仕組み。forwhile が代表的。
  • break: 今いるループを「途中で終了」する。以降の繰り返しはしない。
  • continue: 今いるループの「今回の処理をスキップ」して、次の繰り返しへ進む。
for (let i = 1; i <= 5; i++) {
  if (i === 3) {
    continue; // 3のときだけスキップ
  }
  if (i === 4) {
    break;    // 4が来たらループを終了
  }
  console.log(i); // 1, 2 が出力される
}
JavaScript

ラベルってなに?

  • ラベルの正体: 文(ループ)に「名前」をつける仕組み。名前: と書いてから文を続ける。
  • どこで使う: 主に「ネスト(入れ子)されたループ」で、外側のループに対して breakcontinue を効かせたいときに使う。
  • ないと困る場面: break / continue は通常「一番内側のループ」にしか届かないため、外側を止めたい・飛ばしたい場合に届かない。
outerLoop: for (let i = 1; i <= 3; i++) {
  // outerLoop というラベルを外側のループにつけた
  for (let j = 1; j <= 3; j++) {
    console.log(i, j);
  }
}
JavaScript

例題1: ラベル付き break(外側ごと止める)

  • 目的: 条件を満たしたら「内側だけじゃなく、外側のループごと終了」したい。
  • 使いどころ: もう先に進む意味がない、早退したい(早期終了)。
outer: for (let i = 1; i <= 3; i++) {
  for (let j = 1; j <= 3; j++) {
    const product = i * j;
    console.log(`i=${i}, j=${j}, i*j=${product}`);
    if (product > 5) {
      // 外側のループ outer を終了
      break outer;
    }
  }
}
JavaScript
  • 実行の流れ: i=1, j=1i=1, j=2i=1, j=3i=2, j=1i=2, j=2(ここで 2×2=4)→ i=2, j=3(ここで 2×3=6)で条件成立、外側ごと終了。
  • ポイント: break outer; と書くことで、「どのループを止めたいか」を明示できる。

例題2: ラベル付き continue(外側の次の周回へ)

  • 目的: 条件を満たしたら「外側のループの次の繰り返し」へ進みたい(現在の外側 i の周回を終えて i+1 へ)。
  • 使いどころ: 今の外側の組み合わせはもう不要、次の外側のケースに移りたい。
outer: for (let i = 1; i <= 3; i++) {
  for (let j = 1; j <= 3; j++) {
    if (i === j) {
      // i と j が同じになったら、外側の次の繰り返しへ
      continue outer;
    }
    console.log(`pair: (${i}, ${j})`);
  }
}
JavaScript
  • 実行の流れ(要点): i=1 のとき j=1 で条件成立→外側の i=2 へジャンプ。i=2 のとき j=2 で成立→ i=3 へ。i=3 のとき j=3 で成立→外側終了。
  • ポイント: 単なる continue; だと「内側 j の次」へ進むだけだが、continue outer; は「外側 i の次」へ進む。

例題3: 九九表から特定の列で打ち切る(応用)

  • 目的: 九九を出力しつつ、「ある条件で全体を打ち切り」たい。
  • 学べること: ラベルなしの break とラベルありの break の違いが体感できる。
// ラベルなし(内側しか止まらない)
for (let i = 1; i <= 9; i++) {
  for (let j = 1; j <= 9; j++) {
    if (j === 5) break; // 内側の j ループだけ終了、i は続く
    console.log(`${i} x ${j} = ${i * j}`);
  }
}

// ラベルあり(外側も止める)
stopAll: for (let i = 1; i <= 9; i++) {
  for (let j = 1; j <= 9; j++) {
    if (j === 5) break stopAll; // 全体終了
    console.log(`${i} x ${j} = ${i * j}`);
  }
}
JavaScript
  • 違いの核心: 前者は「各行の 5 列目で行内を打ち切る」だけ。後者は「最初に 5 列目に達した瞬間、表全体を終了」する。

いつ使う?注意点と設計のヒント

  • 便利な場面:
    • 早期終了: 目的が達成されたら即終了(検索・探索・検証の途中で十分な条件を満たしたなど)。
    • スキップ最適化: 今の外側ケースが無意味とわかったら次へ進む。
  • 注意点:
    • 読みやすさ: ラベルが増えると追跡が難しくなる。名前は短く意味が伝わるものに。
    • 過度なネスト: 深い入れ子はそもそも読みにくい。関数化やロジックの分割で解消できることも多い。
    • 代替策: 早期 return(関数に切り出して条件成立時に return)や、フラグ変数で制御する方法も検討。
  • 小さなルール:
    • スコープ: ラベルはつけた文の直前に書く。離れた場所には効かない。
    • 一貫性: break/continue 先のラベルは「存在する外側のループ」を指すこと。別の文を指すと分かりにくくなる。

ミニ練習問題

  • 課題1: 2重ループで、合計が 10 を超えたら「外側ごと」終了するコードを書いてください。
    例: ij を 1..5 で回し、i + j > 10 の瞬間に break で外側を止める。
endAll: for (let i = 1; i <= 5; i++) {
  for (let j = 1; j <= 5; j++) {
    if (i + j > 10) break endAll;
    console.log(i, j);
  }
}
JavaScript
  • 課題2: 2重ループで、i が偶数かつ j が奇数なら「外側の次の i」へ進むコードを書いてください。
nextI: for (let i = 1; i <= 4; i++) {
  for (let j = 1; j <= 4; j++) {
    if (i % 2 === 0 && j % 2 === 1) continue nextI;
    console.log(`i=${i}, j=${j}`);
  }
}
JavaScript
  • 課題3: ラベルを使わずに同じ挙動を作るにはどうするか試してください。
    • ヒント: 関数に切り出して、条件成立時に return する。
タイトルとURLをコピーしました