繰り返す回数が決まっていないときの書き方
for ループは、あらかじめ回数がわかっているときに便利です。「10回繰り返す」「配列のインデックスを全部なめる」といったケースですね。一方の while ループは、そうじゃないとき用 — つまり 何かが変わるまで回し続けたい ときのためのものです。何回ループするかはわからず、止める条件だけがわかっている、そんな場面で使います。
構文はいたってシンプルです:
JavaScript はカッコ内の条件式を評価します。truthy ならブロックを実行し、また条件をチェック、また実行……これを falsy になるまで繰り返します。count++ を書き忘れると条件は永遠に変わらないまま。はい、無限ループのできあがりです。
イメージで押さえる:チェック → 実行 → 繰り返し
while ループがちゃんと動くには、次の 3 つが揃っている必要があります。
- 条件が参照している「何か」があること。
- ループ本体でその「何か」を変更する手段があること。
- いずれ条件が false になること。
どれか 1 つでも欠けるとアウトです。お決まりのバグは、2 番目を忘れるパターン。
let count = 0;
while (count < 5) {
console.log(count);
// count をインクリメントし忘れている — 無限ループになる
}
これを動かすとプロセスを殺すまで止まりません。サーバー上で起きたら大惨事です。ループを書くときは必ず自問してください。本体のどこで条件が false になるのか?
実用例: 終わりが分からないループ
こういう場面でこそ while が for より輝きます。どこかからデータを取り出していって、全部なくなるまで何個あるか分からないケースです。
shift() は先頭の要素を取り出して返すメソッドです。このループはキューに中身がある限り回り続け、空になれば自然に終わります。for でも書けなくはないですが、問題の形に逆らうことになります。while の方が意図がそのままコードに表れるんです。
do...while:まず実行してから条件をチェック
do...while は順番が逆になります。先に本体を実行して、その後 に条件を判定する書き方です。おかげで最低1回は必ず実行されます。
条件が最初から false でも、本体は必ず1回は実行されます。条件が false だと一度もループしない普通の while とは、ここが決定的に違います。
よくあるユースケースは、ユーザーに入力を促して、値を検証し、不正なら再度入力を促すパターン。「最低1回は聞かないと話が始まらない」ので、do...while がぴったりハマります。
閉じカッコ ) のあとのセミコロンを忘れずに。while や for と違って、do...while はこのセミコロンが必須です。
break:ループを途中で抜ける
break を使うと、一番内側のループを即座に抜けられます。条件式だけではうまく表現しきれない「ここで止めたい」という場面で活躍します。
break が実行された瞬間、そのループ内の処理は一切動きません。残りの本体も、次の条件チェックもスキップされ、ループから抜け出します。
while (true) と break の組み合わせ
ループを止める条件をヘッダーに書くより本体の中で表現した方が自然な場合は、発想を逆転させましょう。無限ループにしておいて、終わりたいタイミングで break を使って抜け出すという書き方です。
出口は2つ。成功時のexitと、セーフティキャップとしてのexitです。このセーフティキャップが意外と大事で、break に確実にたどり着く経路がない while (true) は、いつ無限ループになってもおかしくありません。
continue:次のループへスキップする
continue を使うと、そのイテレーションの残りの処理を飛ばして、次の条件チェックへジャンプします。
ループを前に進める処理をcontinueの あと に書いてしまうと、それだけで無限ループの完成です。上のコード例ではn++がcontinueより前にあるのでセーフですが、順番を入れ替えるとnが偶数のまま永遠に止まります。
while と for の使い分け
ざっくりした判断基準はこんな感じです。
- 回数や範囲が決まっているループ →
for。for (let i = 0; i < arr.length; i++)と書けば、カウンタの初期化・条件・更新を1行にまとめられます。 - 配列などのコレクションを順に処理 →
for...of。インデックスを自分で管理しなくていいぶんスッキリ書けます。 - 状態が変わるまで回したい →
while。キューの処理、ポーリング、ストリームの消費、成功するまでリトライ、といった場面にぴったり。 - 最低1回は必ず実行したい →
do...while。
理屈の上ではどれも書き換え可能で、forで書けるものはwhileでも書けますし、その逆も同じです。それでも、問題の形に合ったループを選ぶことで、コード自体が意図を語ってくれるようになります。
無限ループを避けるたった1つのルール
whileループを書くときは、必ず「何がきっかけで終わるのか?」に明確な答えを用意しましょう。
条件式がいずれfalseになるか、もしくは確実に実行されるbreakがあるか。このどちらかを指差して説明できないなら、そのループはまだ未完成です。
// 悪い例: 条件が変化しない
let ready = false;
while (!ready) {
console.log("待機中...");
// この中で `ready` を切り替える処理がない
}
// 良い例: 本体が条件に影響を与える
let ready = false;
let checks = 0;
while (!ready) {
checks++;
if (checks >= 3) ready = true;
}
ブラウザで無限ループに陥るとタブがフリーズしますし、Node.js なら CPU コアを食いつぶしたままプロセスを強制終了するまで止まりません。リリース前に必ず潰しておきたいところです。
次は for...of と for...in
while は「条件が変わるまで繰り返す」というケースに向いています。一方、配列・文字列・オブジェクトを要素ごとに走査したいときのために、JavaScript にはそれ専用のループ構文が 2 つ用意されています。次回はその for...of と for...in を見ていきましょう。
よくある質問
JavaScriptのwhileループとは?
whileループは、条件式がtruthy(真とみなされる値)である限り、ブロック内の処理を繰り返し実行する構文です。JavaScriptはまず条件をチェックしてから処理を実行し、また条件をチェック…という流れを繰り返します。最初のチェックで条件がfalseだった場合は、ブロックは一度も実行されません。
whileとdo...whileの違いは?
whileは処理の前に条件を判定するので、条件次第では一度もループが回らないこともあります。一方のdo...whileは先に処理を1回実行してから条件を判定するため、必ず最低1回は実行される点が大きな違いです。ユーザー入力を受け付ける処理のように「とりあえず1回は実行したい」ケースではdo...whileが便利です。
whileループを途中で抜けるには?
ループを即座に抜けるにはbreak文、現在の周だけスキップして次の周に進むにはcontinue文を使います。while (true)のような無限ループを安全に書きたいときも、このbreakが鍵になります。意図的に無限ループを作り、ブロック内で条件を満たしたタイミングでbreakして抜ける、というパターンです。