JavaScript:繰り返し(for / while / for...of)
1学習の目的
- for と while を使い分けて、同じ処理を自動で繰り返せるようになる。1件しか扱えなかったコードが、100件でも同じ長さで書けるようになる。
- for...of で配列を素直に走査し、break / continue で流れを制御できるようになる。集計・抽出・整形といった実務処理の土台がここで完成する。
2基礎解説
| やりたいこと | 書き方 | 意味 |
|---|---|---|
| 回数を決めて繰り返す | for (let i = 0; i < 5; i++) | 0,1,2,3,4 の5回 |
| 配列を1つずつ処理 | for (const x of items) | 要素を先頭から取り出す |
| 条件が続く間くり返す | while (条件) | falseになるまで繰り返す |
| 抜ける/飛ばす | break / continue | ループ中断/その周回だけスキップ |
- for (let i = 0; i < 5; i++) は「初期値・続ける条件・毎回の更新」の3点セット。セミコロンで区切る。
- 配列を回すなら for...of が最適。番号が不要なら for (const item of items) と書くほうが短く安全。番号も欲しいときは items.entries()。
- for...in は配列に使わない。番号が文字列で返るなど落とし穴が多い。オブジェクト用と覚えておく。
- whileは更新を忘れると無限ループになる。count-- をループ内に必ず書く。ブラウザが固まったらタブを閉じる。
- 合計を出すときはループの前に入れ物を用意する。let total = 0; → ループ内で total += x;。const では再代入できないので let を使う。
現場使用例:商品リストの一覧表示、売上の合計・平均を集計、条件に合うデータだけ抽出、APIが成功するまで再試行 while (!ok)。
// 回数を指定して繰り返す
for (let i = 0; i < 3; i++) {
console.log(i); // 0, 1, 2
}
// 配列を1つずつ取り出す(最もよく使う)
const items = ["りんご", "みかん", "ぶどう"];
for (const item of items) {
console.log(item);
}
// 合計を積み上げる
let total = 0;
for (const n of [1, 2, 3, 4, 5]) {
total += n;
}
console.log(total); // 15
// 条件が満たされる間くり返す
let count = 3;
while (count > 0) {
console.log(count);
count--; // ← これを忘れると無限ループ
}
3基本ドリル(10問)
出力 == 0,1,2,3,4(5行)
for (let i = 0; i < 5; i++) { } の中で console.log(i)。
for (let i = 0; i < 5; i++) {
console.log(i);
}
forの最小形。3つの部分をセミコロンで区切る——初期値 i=0、続ける条件 i<5、毎回の更新 i++。
A. 3回 B. 4回 C. 5回 D. 6回 選択★☆☆無料
解答 == B
i が 1, 2, 3, 4 のときに実行され、5 で条件が false になる。
B
< は「未満」なので5は含まない。1つズレるミスは最頻出のバグ原因で、5回にしたければ i <= 5 か i < 6。
3行「○が好きです」
for (const animal of animals) { } で1つずつ取り出せる。
const animals = ["犬", "猫", "鳥"];
for (const animal of animals) {
console.log(`${animal}が好きです`);
}
番号を経由しないので短く、間違いにくい。取り出した値は変更しないので const で受けるのが基本。
let total = 0;
for (let i = 1; i <= 10; i++) {
total ____ i;
}
console.log(total);
出力 == 55
total に i を足し込む複合代入演算子。
+=
「ループの外で初期化 → ループ内で積み上げ」は集計の基本形。let total = 0 をループの中に書くと毎回リセットされてしまう。
A. 1,2,3が出る B. 1が無限に出続ける C. 何も出ない D. エラーになる 選択★☆☆無料
解答 == B
c の値はどこかで変化しているか?
B
c が1のまま変わらないので条件が永遠にtrue=無限ループ。ブラウザが固まるので、whileを書いたら更新も書くとセットで覚える。
2,4,6,8,10が1行ずつ
更新式を i += 2 にすれば2ずつ進む。
for (let i = 2; i <= 10; i += 2) {
console.log(i);
}
更新式は自由に書ける。i -= 1 や i-- にすれば逆順のカウントダウンにもなる。
let count = 3;
while (count > 0) {
console.log(count);
____;
}
3,2,1が1行ずつ
count を1減らす。デクリメント演算子を使う。
count--
D05で見た無限ループを防ぐ1行。count-- は count -= 1 と同じ意味。
A. ループを完全に抜ける B. その周回の残りを飛ばして次の周回へ進む C. 最初からやり直す D. 処理が止まる 選択★★☆無料
解答 == B
break との違いを考える。
B
break は「ループごと脱出」、continue は「今回だけスキップ」。continue は「不正なデータの行を飛ばす」処理でよく使う。
1,2,3,4が1行ずつ
if で 5 を判定して break。break を console.log より先に書く。
for (let i = 1; i <= 10; i++) {
if (i === 5) {
break;
}
console.log(i);
}
「見つかったら即終了」は検索処理の基本形。break を後に書くと5まで出てしまうので、順序が意味を持つ。
1. 書類 / 2. 印鑑 / 3. 封筒
for (const [i, item] of items.entries()) と書くと番号と要素が同時に取れる。番号は0始まりなので +1 する。
const items = ["書類", "印鑑", "封筒"];
for (const [i, item] of items.entries()) {
console.log(`${i + 1}. ${item}`);
}
[i, item] という書き方は分割代入と呼ぶ。entries() は「番号と値のペア」を返すので、それを2つの変数に分けて受け取っている。
4実践シナリオ(5問)
「合計:65,800円」「平均:13,160円」(平均は小数点なしの整数表示) コーディング★★☆無料
出力2行が完全一致
let total = 0 で初期化してから for...of で足し込む。平均は total / sales.length を Math.round で整数化し、toLocaleString() で3桁区切り。
const sales = [12000, 8500, 23000, 4500, 17800];
let total = 0;
for (const s of sales) {
total += s;
}
const average = Math.round(total / sales.length);
console.log(`合計:${total.toLocaleString()}円`);
console.log(`平均:${average.toLocaleString()}円`);
集計処理の最頻出パターン。.length は要素数を返すプロパティで、カッコは付けない(メソッドではない)。
9行。1行目 7 × 1 = 7、9行目 7 × 9 = 63
for (let i = 1; i <= 9; i++) で回し、テンプレートリテラルの中で n * i を計算する。
const n = 7;
for (let i = 1; i <= 9; i++) {
console.log(`${n} × ${i} = ${n * i}`);
}
${ } の中には式が書けるので、計算結果を別の変数に入れなくてよい。表形式の出力が短く書ける。
合格4件を出力後、最終行 合格者数:4人
ループの中に if を入れる。カウンタ let count = 0 をループの前に用意する。
const scores = [82, 45, 91, 67, 38, 75];
let count = 0;
for (const score of scores) {
if (score >= 60) {
console.log(`合格:${score}点`);
count++;
}
}
console.log(`合格者数:${count}人`);
繰り返し+条件分岐の組み合わせ。JS04で学んだifがそのままループの中で使える。データの絞り込みはすべてこの形。
出力 == 17ヶ月目に達成(残高510,000円)
balance = 0, month = 0 から始め、条件は balance < 500000。ループ内で両方を更新する。
let balance = 0;
let month = 0;
while (balance < 500000) {
balance += 30000;
month++;
}
console.log(`${month}ヶ月目に達成(残高${balance.toLocaleString()}円)`);
繰り返す回数が事前にわからないのでforではなくwhileを使う。これがforとwhileの使い分けの本質。割り算では16.67ヶ月となり「17ヶ月目」が出せない。
20行。3行目 Fizz、5行目 Buzz、15行目 FizzBuzz
「3と5の両方の倍数」=15の倍数。厳しい条件から先に判定する(JS04の鉄則)。
for (let i = 1; i <= 20; i++) {
if (i % 15 === 0) {
console.log("FizzBuzz");
} else if (i % 3 === 0) {
console.log("Fizz");
} else if (i % 5 === 0) {
console.log("Buzz");
} else {
console.log(i);
}
}
プログラミング面接の超定番問題。3の判定を先に書くと15のときFizzしか出ない。JS04の「条件は厳しい順」がそのまま効いてくる。
5仕上げ課題
const sales = [128000, 95000, 143000, 87000, 156000, 112000]; // 1月〜6月
const target = 120000;
仕様:
① 各月を「1月:128,000円」の形式で出力。目標(target)以上の月は末尾に「 ✔達成」を付ける
② 明細の後に --- の行を出す
③ 合計と平均(整数)を1行で出す
④ 達成した月数と、最高売上・その月を1行で出す
出力仕様(10行):
=== 上半期 売上レポート ===
1月:128,000円 ✔達成
2月:95,000円
3月:143,000円 ✔達成
4月:87,000円
5月:156,000円 ✔達成
6月:112,000円
---
合計:721,000円 / 平均:120,167円
達成月:3ヶ月 / 最高:156,000円(5月)
出力10行が完全一致
entries() で月番号と金額を同時に取り出す。合計・達成数・最高額はループ前に let で用意し、1回のループの中でまとめて更新していく。「 ✔達成」は三項演算子で文字列を作ってテンプレートリテラルに埋め込む。
const sales = [128000, 95000, 143000, 87000, 156000, 112000];
const target = 120000;
console.log("=== 上半期 売上レポート ===");
let total = 0;
let achieved = 0;
let best = 0;
let bestMonth = 0;
for (const [i, amount] of sales.entries()) {
const month = i + 1;
total += amount;
const mark = amount >= target ? " ✔達成" : "";
if (amount >= target) {
achieved++;
}
if (amount > best) {
best = amount;
bestMonth = month;
}
console.log(`${month}月:${amount.toLocaleString()}円${mark}`);
}
const average = Math.round(total / sales.length);
console.log("---");
console.log(`合計:${total.toLocaleString()}円 / 平均:${average.toLocaleString()}円`);
console.log(`達成月:${achieved}ヶ月 / 最高:${best.toLocaleString()}円(${bestMonth}月)`);
1回のループで複数の集計を同時に進めるのがポイント。合計・件数・最大値を求めるためにループを3回まわす必要はない。
JS04では1件の配送料しか計算できなかったが、ここでデータが何件あっても同じ長さのコードで処理できるようになった。売上が6ヶ月から60ヶ月に増えても、変えるのは配列の中身だけでコードは1行も変わらない。
次章では配列そのものを深く扱う。push や slice でデータを組み立て・切り出せるようになると、集計の幅が一気に広がる。