目次⇒ 1.繰り返し処理とは? 2.基本のループ文 3.配列の繰り返し処理:基礎編 4.for...ofのメリット・デメリット 5.オブジェクトの繰り返し処理 6.break/continueと無限ループ 7. [コラム] 無限ループの例と防ぎ方 TOP
この記事では、繰り返し処理とは何かについて詳しく解説します。
解説:
プログラミングでは、同じような処理を何度も繰り返す場面がよくあります。
たとえば「リストの中の名前を1人ずつ表示する」「1〜100までの数を順番に足す」など、
似た処理を複数回行いたいときに、繰り返し処理(ループ処理)がめっちゃ役立ちます。
繰り返し処理を使うことで、
// 例:同じ処理を5回行う
console.log("こんにちは!"); // 結果 : こんにちは!
console.log("こんにちは!"); // 〃
console.log("こんにちは!"); // 〃
console.log("こんにちは!"); // 〃
console.log("こんにちは!"); // 〃
これでも動きますが、ループ処理を使えばもっとスマートに書けます。
// 例:同じ処理を5回行う
for (let i = 0; i < 5; i++) {
console.log("こんにちは!");
}
// 結果 : こんにちは! × 5回
たった3行で同じ効果。しかも回数を変えるのも簡単です。
用語のポイント
| 用語 | 意味 |
|---|---|
| 繰り返し処理(ループ) | 一定の条件を満たす間、同じ処理を何度も実行する仕組み |
| 反復(iteration) | ループの1回の繰り返しを「1反復」と呼ぶ |
| カウンタ変数 | 回数を数えるための変数(例:i) |
このように、繰り返し処理は「同じことを何度も書かなくていい」というプログラミングの基本的な考え方を実現するための、大切な仕組みです。
解説: JavaScriptでは、繰り返し処理を行うための基本的な構文として、以下の3種類の繰返し構文があります。
「〇回繰り返したい」といったときによく使うループです。
// 例:1〜5までの数字を表示する
for (let i = 1; i <= 5; i++) {
console.log(i);
}
// 結果 : 1, 2, 3, 4, 5
3つの部分に分かれています:
let i = 1:初期化(最初の値)i <= 5:条件(成り立つ間ループ)i++:変化(1ずつ増やす)条件を満たしている限り、ずっと処理を繰り返します。
// 例:1〜5までの数字を表示する
let i = 1;
while (i <= 5) {
console.log(i);
i++;
}
// 結果 : 1, 2, 3, 4, 5
ポイント:
条件が最初からfalseだと、一度も実行されません。
「まず1回実行してから条件をチェックする」タイプのループです。
// 例:1〜5までの数字を表示する
let i = 1;
do {
console.log(i);
i++;
} while (i <= 5);
// 結果 : 1, 2, 3, 4, 5
ポイント:
条件がfalseでも最低1回は必ず実行されます。
このように、ループ文は状況に応じて使い分けることで、より分かりやすく、安全なコードを書くことができます。
解説:
繰返しと言えば配列、配列と言えば繰返し、切っても切れない関係…?。
配列の中身を順番に処理したいときの方法「for」文・「for...of」文・「forEach」メソッドの3つを紹介します!
インデックス(番号)を使って、配列の各要素にアクセスします。
// 例:配列の全要素を表示する
const fruits = ["りんご", "みかん", "バナナ"];
for (let i = 0; i < fruits.length; i++) { // 「配列.length」で配列の長さ(要素の個数)が取得できるを利用しています!
console.log(fruits[i]); // 「length」はプロパティなので()は不要です
}
// 結果 : りんご, みかん, バナナ
特徴: インデックスを明示的に使うため、i を元に別の処理がしやすいです。
配列の「中身」に直接アクセスする書き方です。
// 例:配列の全要素を表示する
const fruits = ["りんご", "みかん", "バナナ"];
for (const fruit of fruits) { // fruitsの中身を1つずつfruitに取り出して処理してます
console.log(fruit);
}
// 結果 : りんご, みかん, バナナ
特徴: インデックスが不要な場合におすすめ。コードがすっきりします。
配列の各要素に対して、関数を使って処理を行います。
// 例:配列の全要素を表示する
const fruits = ["りんご", "みかん", "バナナ"];
fruits.forEach(function(fruit) { // fruitsの中身を1つずつfruitに取り出して処理してます
console.log(fruit);
});
// 結果 : りんご, みかん, バナナ
アロー関数で書くと、さらに簡潔になります:
// アロー関数バージョン
fruits.forEach((fruit) => { // fruitsの中身を1つずつfruitに取り出して処理してます
console.log(fruit);
});
// 結果 : りんご, みかん, バナナ
| 文法 | 特徴 | こんなときに使う |
|---|---|---|
for |
柔軟・細かい制御が可能 | インデックスが必要なとき |
for...of |
シンプルで読みやすい | 全要素を順に処理したいとき |
forEach |
関数ベースでスッキリ書ける | 後で map や filter に発展させたいとき |
どれもよく使われる繰り返し方法になります。
しっかりとマスターしましょう!
次は「for...of」が実は万能ではない理由を見ていきます!
解説:
「for...of」は、配列の各要素の処理を短くシンプルに書ける便利な文法です。
でも、「便利」=「万能」というわけではありません。
この章では、「for...of」の強みと弱みの両方を紹介します。
まず、「for...of」の読みやすさ・書きやすさは、トップクラスと言えます。
// 例:配列の要素を順番に表示する
const animals = ["ねこ", "いぬ", "うさぎ"];
for (const a of animals) {
console.log(a);
}
// 結果 : ねこ, いぬ, うさぎ
インデックス変数「i」を意識せず、「中身」だけに集中できます。
これだけで、書けるのは、ほんと楽!
「for...of」では、今「何番目」を処理しているか分かりません。
// 例:無理にindexを使おうとしてもエラーになります
for(const a of animals) {
console.log(a, i); // 結果 : undefined エラー
} // 「i」は未定義のため「〇番目の要素だけ特別な処理をしたい」など、位置に応じた処理がしたい場合は「for」文や「forEach」を使いましょう。
// forEach なら index も取れます
animals.forEach((a, i) => { //(a, i)とすると、引数1のaには要素、引数2のiにはインデックス(要素番号)が入ります
console.log(i + 1, '番目: ', a);
});
// 結果 : 1番目: ねこ ...「for...of」は「反復可能(iterable)」なオブジェクトにしか使えません。
// オブジェクトには使えません(エラー)
const obj = { a: 1, b: 2 };
for (const item of obj) {
console.log(item);
}
// ❌ TypeError: obj is not iterable
オブジェクトをループするときは、「for...in」や「Object.keys()」を使います(次章で解説します)。
| 特性 | 内容 |
|---|---|
| 向いている👍 | 配列など「順に中身を取り出す」処理。読みやすく、コードも簡潔。 |
| 向いていない👎 | インデックスが必要な処理/オブジェクトのループ処理 |
「シンプルに書きたい」ときには便利な「for...of」。
でも「番号を使いたい」「オブジェクトを回したい」ときは、別の方法を選ぶのがベストです。
次は、オブジェクトを繰り返し処理する方法を学びましょう!
解説:
第4章では「for...of」は配列専用と紹介しました。次は、オブジェクト(連想配列)の中身を順番に処理する場合です。
JavaScriptには、オブジェクトを繰り返し処理するための方法がいくつか用意されています。
代表的なのは 「for...in」文 と 「Object.keys()」+ ループ の組み合わせです。
オブジェクトのキー(プロパティ名)を1つずつ取り出す方法です。
// 例:オブジェクトの中身を表示
const user = { name: "太郎", age: 25, city: "東京" };
for (const key in user) {
console.log(key, ":", user[key]);
}
// 結果 :
// name : 太郎
// age : 25
// city : 東京
「key」にはプロパティ名("name" や "age")が入ります。
値を取りたい場合は、変数として扱えるブラケット記法(user[key])を使います。
「user.key」のようなドット記法では、「key」という名前のプロパティを探してしまうため、
誤って使わないように注意してください!
オブジェクトのキーを配列として取得し、それを配列としてループする方法です。
// Object.keys() を forEach で回す
const user = { name: "太郎", age: 25, city: "東京" };
Object.keys(user).forEach((key) => {
console.log(key, ":", user[key]);
});
// 結果 : name : 太郎, age : 25, city : 東京for...in より安全で実務向きとも言われます。理由は次のとおりです:
| 方法 | 特徴 | 向いている場面 |
|---|---|---|
| for...in | シンプルで歴史が長い | 初心者向け。ざっくり中身を確認したいとき |
| Object.keys() | 意図したキーだけ、安全に取り出せる | 実務でのループ処理や後続の配列処理に応用したいとき |
オブジェクトをループするときには、「何を取り出したいのか」「何をしたいのか」で方法を選びましょう。
次は、ループを途中で抜ける「break / continue」について解説していきます。
解説:
繰り返し処理の中では「特定の条件で抜けたい」「一部だけスキップしたい」といった場面がよくあります。
そうしたときに使えるのが、break と continue です。
また、これらを正しく理解しておかないと、「無限ループ」に陥ってしまうこともあります。
break を使うと、ループの途中でも条件を満たした時点でループを終了できます。
// 例:3が見つかったらループ終了
for (let i = 1; i <= 5; i++) {
console.log(i);
if (i === 3) {
break;
}
}
// 結果 : 1, 2, 3「3まで見つけたらそれ以降はもう不要」という場合に便利です。
continue を使うと、特定の条件のときだけ処理を飛ばして次の繰り返しに進むことができます。
// 例:3だけスキップする
for (let i = 1; i <= 5; i++) {
if (i === 3) {
continue;
}
console.log(i);
}
// 結果 : 1, 2, 4, 5「3だけ飛ばして他の処理を続けたい」といったときに使えます。
ループの条件や終了処理を正しく書かないと、永遠に終わらない無限ループになってしまうことがあります。
// これは注意!i が増えないので永遠にループ
let i = 0;
while (i < 5) {
console.log(i);
// i++ を書き忘れている!
}
// 結果 : 0 が延々と出力され続ける無限ループの原因あるある:
ブラウザの開発者ツールで実行してしまうと、止まらなくなることがあるので注意!
どうしても止まらないときは、ブラウザを強制リロードしてください(F5 や Ctrl + R)。
| キーワード | 意味 | 使いどころ |
|---|---|---|
| break | ループを強制終了する | 特定の条件を満たしたら処理を終えたいとき |
| continue | その回の処理だけスキップ | 一部だけ処理を飛ばして、次に進みたいとき |
| 無限ループ | ループが永遠に終わらない状態 | 条件やカウンタの書き忘れに注意 |
無限ループは実行環境を止めてしまう危険があるため、最初は「回数固定の for 文」から始めるのがおすすめです。
次は、実践でよく使われる配列の繰り返し(map / filter / reduce)に進みましょう!
解説:
「気づいたら画面が止まった...!」「タブがクラッシュした...!」
そんな“無限ループの恐怖”に、一度はやられたことがある人も多いのではないでしょうか。
かくいう私も、ちょいちょい勘違いしてやらかしてます...笑
このコラムでは、よくある無限ループのパターンと、それを防ぐためのちょっとしたテクニックを紹介します。
// i++ を書き忘れた!
let i = 0;
while (i < 10) {
console.log(i);
// i++ を忘れている!
}
// 結果 : 0 が延々と出力され続ける初心者あるあるの代表格です。カウント変数が増えない=条件が永遠にtrueという罠。
// continue で i++ が実行されない場合
let i = 0;
while (i < 5) {
if (i === 2) {
continue; // i++ がスキップされる!
}
console.log(i);
i++;
}
// 結果 : 0, 1, 無限ループ突入!continue を入れる位置によっては、意図せずループが止まらなくなることも。
// 条件がずっと true
while (true) {
console.log("ずっと表示される!");
}
// 結果 : 無限ループ確定テストで使ってそのまま忘れるパターン。終了条件を忘れずに!
無限ループは、実行環境によっては「動かなくなる」「ブラウザが固まる」などのトラブルにもつながります。
「ちゃんと止まる」ことを、プログラムではとても大事にしましょう。
これにて、基本編は終了!👏お疲れさまでした!
次章からはいよいよ実践編。実務でも大活躍する map / filter / reduce の世界に入っていきます!