
JavaScriptのループ処理(for, while)
2025-07-28はじめに
JavaScriptのループ処理は、同じ処理を繰り返し実行する仕組みです。for
文は回数が決まっている繰り返しに向き、while
文は条件が真である間繰り返します。条件式やカウンタを使って効率的に処理を制御できます。
ループ処理の基本概念
ループ処理は、特定の条件が満たされている間、同じ処理を繰り返し実行するための仕組みです。JavaScriptには主に以下のループ構文があります:
for
ループwhile
ループdo...while
ループfor...in
ループ(オブジェクト用)for...of
ループ(イテラブルオブジェクト用)
forループ
特徴:初期化・条件判定・更新処理を一行で書き、回数が決まっている繰り返しに向く。
ポイント:繰り返しの開始・終了が明確で、カウンタ変数を使って制御しやすい。可読性が高い。
基本的なforループ
for (let i = 0; i < 5; i++) {
console.log(i); // 0, 1, 2, 3, 4
}
構成要素:
- 初期化式 (
let i = 0
): ループ開始時に1回だけ実行 - 条件式 (
i < 5
): 各ループ前に評価され、trueなら実行 - 更新式 (
i++
): 各ループ後に実行
応用的なforループ
// 複数の変数を初期化
for (let i = 0, j = 10; i < j; i++, j--) {
console.log(`i:${i}, j:${j}`);
}
// 要素をスキップ
for (let i = 0; i < 10; i++) {
if (i % 2 === 0) continue; // 偶数はスキップ
console.log(i); // 1, 3, 5, 7, 9
}
// ループを途中で終了
for (let i = 0; i < 10; i++) {
if (i === 5) break; // iが5になったら終了
console.log(i); // 0, 1, 2, 3, 4
}
whileループ
特徴:条件が真(true)の間、処理を繰り返す。繰り返し回数が不定の場合に使う。
ポイント:条件を必ず更新しないと無限ループになるので注意。ループ前に条件判定が行われる。
基本的なwhileループ
let count = 0;
while (count < 5) {
console.log(count); // 0, 1, 2, 3, 4
count++;
}
無限ループとその回避
// 意図しない無限ループの例
let x = 0;
while (x < 5) {
console.log(x);
// x++を忘れていると無限ループ
}
// 意図的な無限ループ(抜け道あり)
while (true) {
let input = prompt('「exit」と入力してください');
if (input === 'exit') break;
}
do…whileループ
let result;
do {
result = prompt('「yes」と入力してください');
} while (result !== 'yes');
特徴:
- 条件式が後ろにあるため、最低1回は実行される
- ユーザー入力の確認などに適している
ループ制御文
ループ制御文は、break
やcontinue
を使ってループの実行を途中で止めたり、特定の繰り返しだけスキップしたりするための命令です。break
はループ全体を終了し、continue
は現在の繰り返しを飛ばして次の繰り返しに進みます。これにより、細かい処理の制御が可能になります。
break文
for (let i = 0; i < 10; i++) {
if (i === 5) {
break; // ループを抜ける
}
console.log(i); // 0, 1, 2, 3, 4
}
continue文
for (let i = 0; i < 10; i++) {
if (i % 2 === 0) {
continue; // 次のループに進む
}
console.log(i); // 1, 3, 5, 7, 9
}
ループのネスト
ループのネストとは、ループの中にさらに別のループを入れることです。これにより、多次元データの処理や組み合わせの全探索など、複雑で階層的な繰り返し処理が可能になります。
例えば、二重ループを使えば「2次元の表(行と列)のすべてのセルを順に処理」や「複数のリストからすべての組み合わせを作る」ことができます。こうした処理は1つのループだけでは難しいため、ネストが役立ちます。
// 九九の表を作成
for (let i = 1; i <= 9; i++) {
let row = '';
for (let j = 1; j <= 9; j++) {
row += `${i * j}\t`;
}
console.log(row);
}
配列の反復処理
配列は複数のデータを順番にまとめて管理するデータ構造であり、反復処理と非常に相性が良いです。ループ(forやwhile)を使うことで、配列の全要素に効率よくアクセス・処理ができるため、繰り返し操作が簡単かつ高速に行えます。また、forEach
やmap
などの専用メソッドもあり、コードがシンプルで読みやすくなります。これにより、大量のデータ処理や一覧表示がスムーズに実装可能です。
伝統的なforループ
const fruits = ['apple', 'banana', 'orange'];
for (let i = 0; i < fruits.length; i++) {
console.log(fruits[i]);
}
for…ofループ(ES6)
for (const fruit of fruits) {
console.log(fruit);
}
forEachとmapメソッドの使用例
const numbers = [1, 2, 3, 4, 5];
// forEachの例(配列の要素を1つずつコンソールに表示)
numbers.forEach(num => {
console.log(num);
});
// mapの例(配列の各要素を2倍にして新しい配列を作る)
const doubled = numbers.map(num => num * 2);
console.log(doubled); // [2, 4, 6, 8, 10]
forEachやmapメソッドについて別途詳しく説明してます。
パフォーマンスの最適化
- ループ外でlengthをキャッシュ:
for (let i = 0, len = array.length; i < len; i++) {
// 処理
}
- 逆順ループ:
for (let i = array.length - 1; i >= 0; i--) {
// 処理
}
- ループの展開:
for (let i = 0; i < array.length; i += 4) {
process(array[i]);
process(array[i+1]);
process(array[i+2]);
process(array[i+3]);
}
ループのベストプラクティス
- 適切なループを選択:
- 回数が決まっている →
for
- 条件による繰り返し →
while
/do...while
- 配列の反復 →
for...of
またはforEach()
- 無限ループを避ける:
- 必ず終了条件を確認
while(true)
には必ずbreak
を用意
- 可読性を重視:
- 複雑なループはコメントを追加
- ネストは3段階までが目安
- 副作用を最小限に:
- ループ内で外部変数を変更しない
- 可能なら関数型プログラミングを採用
まとめ
ループ処理は大量のデータや繰り返し作業を自動化し、コードを簡潔にします。for
は回数指定、while
は条件依存と覚えると使い分けやすく、効率的なプログラムが書けます。
演習問題
初級問題(3問)
- 次のforループをwhileループに書き換えなさい。
for (let i = 0; i < 5; i++) {
console.log(i);
}
- whileループの危険性を説明し、修正してください。
以下のコードは、1から10までの数字を順番に出力することを意図していますが、実行するとプログラムが止まりません。なぜこのような動作になるのか説明し、正しく修正してください。
let i = 1;
while (i <= 10) {
console.log(i);
}
- 次のコードの出力結果は?
let x = 0;
while (x < 3) {
console.log(x);
x++;
}
中級問題(6問)
- 次のコードの間違いを指摘し、修正しなさい。
for (let i = 10; i > 0; i--) {
console.log(i);
}
console.log('最後のiの値:', i);
- 次の配列の要素を逆順に出力するプログラムを書きなさい。
const colors = ['red', 'green', 'blue', 'yellow'];
- 1から100までの数字で、偶数のときは 'Even'、奇数のときは 'Odd' を出力しなさい。それ以外は何も出力しなくてよい。
- 次のコードの出力結果とその理由を説明しなさい。
for (let i = 0; i < 5; i++) {
if (i === 2) continue;
if (i === 4) break;
console.log(i);
}
- ネストされたループを使用して、次のパターンを出力するプログラムを書きなさい。
*
**
***
****
*****
- 次のオブジェクトのプロパティ名と値を
for...in
ループを使って表示しなさい。
const person = {
name: '山田太郎',
age: 30,
occupation: 'エンジニア'
};
上級問題(3問)
- 次の2次元配列のすべての要素の合計を計算するプログラムを書きなさい。
const matrix = [ [1, 2, 3], [4, 5, 6], [7, 8, 9] ];
- 素数判定プログラムを作成しなさい。引数として与えられた数が素数かどうかを判定する関数
isPrime
を実装しなさい。
- フィボナッチ数列の最初の20項を配列として生成するプログラムを書きなさい。
フィボナッチ数列は次のように定義されます。最初の2つの数字が1で、それ以降の数字が前の2つの数字の和で表される数列のことです。具体的には、1, 1, 2, 3, 5, 8, 13, 21, 34, … のように続きます。
F₀ = 0
F₁ = 1
Fₙ = Fₙ₋₁ + Fₙ₋₂ (n ≥ 2)
解答例
初級問題解答
- forループをwhileループに書き換え。
let i = 0;
while (i < 5) {
console.log(i);
i++;
}
- whileループの危険性と修正
カウンター変数iをインクリメントしなければ無限ループする。
let i = 1;
while (i <= 10) {
console.log(i);
i++; // カウンターをインクリメントしてループを終わらせる
}
- コードの出力結果
0
1
2
中級問題解答
- 間違いと修正
// 間違い: ループ外でiを参照しようとしている(ブロックスコープ)
// 修正例1(letをvarに変更):
for (var i = 10; i > 0; i--) {
console.log(i);
}
console.log('最後のiの値:', i);
// 修正例2(ループ外で変数を宣言):
let j;
for (j = 10; j > 0; j--) {
console.log(j);
}
console.log('最後のjの値:', j);
- 配列の逆順出力
for (let i = colors.length - 1; i >= 0; i--) {
console.log(colors[i]);
}
- 偶数 'Even'と奇数 'Odd'
for (let i = 1; i <= 100; i++) {
if (i % 2 === 0) {
console.log('Even');
} else {
console.log('Odd');
}
}
- コードの出力結果とその理由
0
1 // i=2のときcontinueでスキップ
3 // i=4のときbreakでループ終了
for (let i = 0; i < 5; i++) {
if (i === 2) continue; // i=2のときcontinueでスキップ
if (i === 4) break; // i=4のときbreakでループ終了
console.log(i);
}
- パターンを出力するプログラム
for (let i = 1; i <= 5; i++) {
let stars = '';
for (let j = 0; j < i; j++) {
stars += '*';
}
console.log(stars);
}
- オブジェクトのプロパティ名と値を
for...in
ループを使う
for (const key in person) {
console.log(`${key}: ${person[key]}`);
}
上級問題解答
- 2次元配列の合計を計算するプログラム
let total = 0;
for (let i = 0; i < matrix.length; i++) {
for (let j = 0; j < matrix[i].length; j++) {
total += matrix[i][j];
}
}
console.log(total); // 45
- 素数判定判定プログラム
function isPrime(num) {
if (num <= 1) return false;
if (num === 2) return true;
for (let i = 2; i <= Math.sqrt(num); i++) {
if (num % i === 0) return false;
} return true;
}
- フィボナッチ数列20項を配列として生成するプログラム
const fibonacci = [0, 1];
for (let i = 2; i < 20; i++) {
fibonacci[i] = fibonacci[i - 1] + fibonacci[i - 2];
}
console.log(fibonacci);