JavaScriptのループ
ループを使えば、コードブロックを繰り返し実行できます。「こんにちは」を100回手書きするのは馬鹿げていますが、ループを使えば1回書くだけです。それがループの力です。
forループ
forループは繰り返し回数がわかっている場合にもっともよく使われる選択肢です:
<!DOCTYPE html>
<html lang="ja">
<head><meta charset="UTF-8"><title>forループ</title></head>
<body>
<div id="output"></div>
<script>
for (let i = 0; i < 5; i++) {
document.getElementById('output').textContent += i + ' ';
}
</script>
</body>
</html>
3つの部分:
let i = 0— 初期化、1回だけ実行i < 5— 条件、各繰り返しの前にチェック。trueの場合のみ続行i++— 更新、各繰り返しの後に実行
💪 ループ変数は慣例的に
iと名付けられます。ネストしたループでは、外側にi、内側にj、さらにその次にkを使います — プログラマーの普遍的な慣習です。
実例:ループでリストを生成
<!DOCTYPE html>
<html>
<body>
<h2>ループでリストを生成</h2>
<ul id="list"></ul>
<script>
let fruits = ['りんご', 'バナナ', 'オレンジ', 'ぶどう', 'すいか'];
let html = '';
for (let i = 0; i < fruits.length; i++) {
html += `<li>#${i + 1}: ${fruits[i]}</li>`;
}
document.getElementById('list').innerHTML = html;
</script>
</body>
</html>
whileループ
whileは条件を先にチェックしてから実行します。繰り返し回数がわからない場合に最適です:
<script>
let count = 0;
while (count < 3) {
count++;
}
</script>
よくあるユースケース:データがなくなるまで読み込む、条件がtrueになるまで待つ。
do...whileループ
do...whileは条件をチェックする前に1回実行します。少なくとも1回は実行されます:
<script>
let input;
do {
input = prompt('正の数を入力してください:');
} while (Number(input) <= 0);
</script>
whileとの違いを一言で言うと:whileは1回も実行されない可能性がありますが、do...whileは常に少なくとも1回実行されます。
実例:3つのループの比較
<!DOCTYPE html>
<html>
<body>
<h2>3つのループタイプの比較</h2>
<div id="output"></div>
<script>
let html = '<strong>forループ:1〜5を出力:</strong><br>';
for (let i = 1; i <= 5; i++) {
html += i + ' ';
}
html += '<br><br><strong>whileループ:カウントダウン:</strong><br>';
let count = 5;
while (count > 0) {
html += count + '... ';
count--;
}
html += '発射!';
html += '<br><br><strong>do...while:少なくとも1回実行:</strong><br>';
let x = 100;
do {
html += '実行されました! x = ' + x + '<br>';
x++;
} while (x < 100);
// 条件は最初からfalseだが、doブロックは1回実行される
document.getElementById('output').innerHTML = html;
</script>
</body>
</html>
for...ofループ
for...ofは反復可能オブジェクト(配列、文字列など)を反復するために設計された、最もクリーンな構文です:
<!DOCTYPE html>
<html lang="ja">
<head><meta charset="UTF-8"><title>for...of</title></head>
<body>
<div id="output"></div>
<script>
let colors = ['赤', '緑', '青'];
let html = '';
for (let color of colors) {
html += color + ' ';
}
document.getElementById('output').textContent = html;
</script>
</body>
</html>
forとは異なり、for...ofはインデックスではなく値を返します。インデックスが必要な場合は、従来のforループを使います。
💪
for...ofで文字列を反復すると、1文字ずつ取得できます。絵文字も intact に保たれるため、インデックスベースのアクセスよりもはるかに信頼性があります。
breakとcontinue
break— ループ全体を即座に終了するcontinue— 現在の繰り返しをスキップして次に進む
<!DOCTYPE html>
<html lang="ja">
<head><meta charset="UTF-8"><title>breakとcontinue</title></head>
<body>
<div id="output"></div>
<script>
// break:対象が見つかったら停止
let breakResult = '';
for (let i = 0; i < 10; i++) {
if (i === 5) break;
breakResult += i + ' ';
}
// continue:偶数をスキップ
let continueResult = '';
for (let i = 0; i < 6; i++) {
if (i % 2 === 0) continue;
continueResult += i + ' ';
}
document.getElementById('output').innerHTML =
'<strong>breakの結果:</strong>' + breakResult + '<br>' +
'<strong>continueの結果:</strong>' + continueResult;
</script>
</body>
</html>
実例:breakとcontinueの実践
<!DOCTYPE html>
<html>
<body>
<h2>breakとcontinue</h2>
<div id="output"></div>
<script>
let html = '<strong>break — 最初の偶数で停止:</strong><br>';
let nums = [1, 3, 7, 4, 9, 2];
for (let n of nums) {
if (n % 2 === 0) {
html += `偶数${n}が見つかりました。停止!`;
break;
}
html += `${n}は奇数、続行中...<br>`;
}
html += '<br><br><strong>continue — 奇数のみ出力:</strong><br>';
for (let i = 1; i <= 10; i++) {
if (i % 2 === 0) continue;
html += i + ' ';
}
html += '<br><br><strong>実践例 — 検索:</strong><br>';
let students = [
{ name: '花子', score: 95 },
{ name: '太郎', score: 72 },
{ name: '一郎', score: 88 }
];
let found = false;
for (let s of students) {
if (s.score >= 90) {
html += `優秀な生徒を発見: ${s.name}(${s.score}点)`;
found = true;
break;
}
}
if (!found) {
html += '90点以上の生徒はいません';
}
document.getElementById('output').innerHTML = html;
</script>
</body>
</html>
ネストしたループ
ループは他のループの中にネストできます。2次元データ(テーブル、グリッド)の操作に最もよく使われます:
<!DOCTYPE html>
<html lang="ja">
<head><meta charset="UTF-8"><title>ネストしたループ</title></head>
<body>
<div id="output"></div>
<script>
let html = '';
for (let i = 0; i < 3; i++) {
for (let j = 0; j < 3; j++) {
html += `(${i}, ${j}) `;
}
html += '<br>';
}
document.getElementById('output').innerHTML = html;
</script>
</body>
</html>
ネストしたループはコストが乗算されます。外10 × 内10 = 100回の繰り返しです。深すぎると大幅に遅くなるため、代替手段があれば深いネストを避けましょう。
実例:九九の表
<!DOCTYPE html>
<html>
<body>
<h2>九九の表</h2>
<table id="table" border="1" cellpadding="6" style="border-collapse:collapse"></table>
<script>
let html = '';
for (let i = 1; i <= 9; i++) {
html += '<tr>';
for (let j = 1; j <= i; j++) {
html += `<td style="text-align:center">${j}×${i}=${i * j}</td>`;
}
html += '</tr>';
}
document.getElementById('table').innerHTML = html;
</script>
</body>
</html>
無限ループの落とし穴
ループの条件が常にtrueの場合、プログラムがフリーズします。これが無限ループです:
<script>
// ⚠️ 絶対にやらないでください!
// while (true) {
// console.log('止まれない!');
// }
// よくある間違い:条件の更新を忘れる
let i = 0;
// while (i < 5) {
// console.log(i);
// i++を忘れたので、iは常に0でループが終わらない
// }
</script>
📖 まとめ
forは繰り返し回数が既知の場合に最も一般的。whileは条件駆動型、do...whileは少なくとも1回実行for...ofは配列を反復する最もクリーンな方法 — インデックスではなく値を返すbreakはループ全体を終了し、continueは次の繰り返しにスキップする- ネストしたループは繰り返し回数が乗算される — 深くなりすぎないように注意
- 無限ループを避けるため、ループの条件がいつかfalseになることを常に確認する
❓ よくある質問
for...ofとfor...inの違いは何ですか?for...ofは値を反復し、配列や反復可能オブジェクトで動作します。for...inはキー(インデックス)を反復し、オブジェクト向けです。配列にはfor...ofを使いましょう — for...inはプロトタイプチェーンのプロパティを拾い、予期しない問題を引き起こす可能性があります。forループが最も高速で、for...ofはやや遅いですがより読みやすいです。ほとんどの場合、パフォーマンスの差は無視できる程度なので、可読性を優先しましょう。breakはすべてのループを抜けますか?それとも内側だけですか?outer: for(...) { for(...) { break outer; } }。ただしラベルは可読性を損なうため、関数にリファクタリングしてreturnを使うことを検討しましょう。📝 演習
forループを使って、1から100までの3の倍数をすべて表示してください。- ネストしたループを使って、8×8の市松模様(白と黒の交互パターン)をページに描画してください。
- 正の整数を入力として受け取り、その階乗を出力するプログラムを書いてください(例:入力5 → 5×4×3×2×1 = 120)。



