プログラミングを行う際に、何かしらの条件に応じて繰り返しの処理を行う機会があります。
JavaScriptで繰り返し処理をするために用意されているのがfor文やwhile文です。

今回はfor文を取り上げて、繰り返し処理方法を解説します。

繰り返し処理

繰り返し処理とは、ある条件下において何らかの行為を繰り返し実行するための処理です。ループ(Loop)とも言われています。

例えば、ユーザーがクイズアプリの回答をしている場面を考えてみましょう。
「5問正解するまでは問題を出し続け、5問正解したら別画面に切り替わる」といった実装では、正解数が5回に達するまで問題を出し続ける、つまり繰り返し処理を行う必要があります。

こうしたときに役立つのがfor文を使った繰り返し処理です。

for文

for文とは、決められた回数だけ繰り返し処理を行う制御文です。
以下がfor文の基本構文です。

for (初期化式; 条件式; 変化式) {
  実行する処理1;
  実行する処理2;
  実行する処理3; 
}

ブロック{}に囲まれた文が、繰り返し行いたい処理です。

繰り返し処理文が1つだけの場合、ブロックを省略して一行で書くこともできます。
処理文が短いものは、このように一行に書くことで可読性が上がります。

for (初期化式; 条件式; 変化式) 実行する処理;

サンプルコードを見てください。

for (let i = 0; i < 5; i++) {
  console.log((i + 1) + '回目の処理です');
 }

// '1回目の処理です'
// '2回目の処理です'
// '3回目の処理です'
// '4回目の処理です'
// '5回目の処理です'

ある条件に沿って処理が5回繰り返された結果です。

for文の括弧()の中の式は、以下のように構成されています。

初期化式

初期化式には、変数宣言を用いて変数の初期値を設定します。

変数iはカウンタ変数と呼ばれ、繰り返し処理を制御するための慣習としてアルファベットのiが使われています。
カウンタ変数の値に決まりはありませんが、通常は初期値を0にすることが好ましいです。理由は、0から始まる配列のインデックス番号を操作する際に都合が良いためです。

条件式

条件式には、どのような条件下で処理を行いたいか記述します。

上記のコードでは、「カウンタ変数が5よりも小さい場合」と条件の設定をしています。

変化式

変化式には、処理が終わるごとに、どのようにカウンタ変数を変化させるか記述します。

上記のコードでは、処理が終わるごとに、カウンタ変数の値を1ずつ加算するようにしています。
全体の処理の流れを追っていくと、次のようになります。

  1. 初期化式let i = 0が実行される
  2. 条件式i < 5が評価される。trueの場合はfor文のブロック内の処理に進み、falseの場合はfor文のループから抜ける
  3. ブロック内の処理console.log((i + 1) + '回目の処理です')が実行される
  4. 変化式i++が実行される
  5. 2のステップに戻り、条件式の評価が行われる

for…in文

for…in文は、オブジェクト(連想配列)に格納されたすべての列挙可能なプロパティに対して、順不同で繰り返し処理を行います。
プロパティの数の分だけ繰り返し処理が行われ、その都度変数の中にプロパティが一つずつ格納されます。

for…in文の基本構文は以下です。

for (変数 in オブジェクト) {
  実行する処理;
}

サンプルコード

let obj = {
  year: 2020,
  month: 12,
  date: 31
}; 

for (let item in obj) {
  console.log(item);
}

// 'year'
// 'month'
// 'date'

変数にはキーが格納されます。

また、オブジェクト[変数]のようにして、オブジェクトの値を参照することも可能です。

let obj = {
  year: 2020,
  month: 12,
  date: 31
}; 

for (let item in obj) {
  console.log(obj[item]);
}

// 2020
// 12
// 31

このようにfor…inを使用することで、オブジェクトに格納したキーや値を調べることができます。

しかしfor…inは、順不同に処理が行われることに注意が必要です。実行すると大体の場合はプロパティの格納順に処理が実行されますが、順番が保証されているものではありません。
つまり、上記のプロパティの値が「31→12→2020」という順番で出力される可能性もあるということです。
順番に意味があるオブジェクトを操作する場合は、以下で解説するfor…ofを使用すると良いでしょう。

for…of文

for…of文は、iterableオブジェクトと呼ばれる反復可能なオブジェクトに対して、順番に繰り返し処理を行います。
iterableオブジェクトの代表的なものとして配列があげられます。
配列に含まれる要素が変数として取り出され、要素の数分の繰り返し処理が行われることが特徴です。

for…of文の基本構文は以下です。

for (変数 of 配列) {
  実行する処理;
}

サンプルコード

let array = [100, 200, 300];

for (let item of array) {
  console.log(item);
}

// 100
// 200
// 300

for…inとは異なり、配列の値がそのまま順番に変数に入るため、使いやすいです。

また、以下のように文字列に対しても列挙させることができます。

const string = '文字列';

for (const value of string) {
  console.log(value);
}

// '文
// '字'
// '列'

for…ofは、配列や文字列以外にも、MapやSetなどの複数のiterableオブジェクトに対して使用することができるため、習得しておくと便利です。

オブジェクトのプロパティに対して繰り返し処理が必要な場合はfor…inを使い、それ以外はfor…ofを使用すると良いでしょう。

continueとbreak

ここまでfor文の使い方を解説してきましたが、もう少し複雑な処理を行う際に使えるcontinueとbreakについても知っておくと便利です。
どちらもif文と一緒に使うことで、ループの中で処理を飛ばす働きをします。

continue

for (let i = 0; i < 10; i ++) { 
  実行する処理1; 
  if (条件式) continue; // trueの間は処理2をスキップする
  実行する処理2;
}

continueを使用すると、if文の条件式がtrueの間はそれ以降の処理をスキップします。
if文の条件式がfalseになると繰り返し処理中の文の処理がスキップされ、次の処理に渡ります。

break

for (let i = 0; i < 10; i ++) { 
  実行する処理1; 
  if (条件式) break; // trueになるとループから抜けるため、処理2をスキップする
  実行する処理2; 
}

breakは、if文の条件式がtrueになると繰り返し処理の途中であっても強制的にループから抜けることになり、繰り返し処理は終了となります。

実際の例を見てみましょう。

for (let i = 0; i < 10; i ++) {
  console.log(i); 
  if (i < 5) {
    continue;
  } else {
    console.log(i + 'になったのでループから抜けます');
    break;
  }
}

// 0
// 1
// 2
// 3
// 4
// 5
// '5になったのでループから抜けます'

変数が4までの間は、変数の値が繰り返し出力されます。
変数が5に到達すると、continueにより処理がスキップされ、if文を抜いた処理が実行されます。
else文のbreakにたどり着くと繰り返し処理は終了です。

このように、continueやbreakを使用すると、さらに細かい繰り返し処理の制御ができるようになります。

まとめ

今回は、for文を使った繰り返し処理について解説しました。

繰り返し処理の方法はさまざまありますが、まずは基本であるfor文が使えるようになると便利です。

// ポイント
* for文は、決められた回数だけ繰り返し処理を実行する
* for…in文は、オブジェクトのプロパティに対する繰り返し処理
* for…of文は、配列の要素に対する繰り返し処理
* continueとbreakで繰り返し処理を細かく制御する

以上のことを意識してfor文の繰り返し操作に取り組んでいきましょう。

合わせて読みたい繰り返し処理入門シリーズ

第1回:繰り返し処理 -for文(当記事)
第2回:繰り返し処理 -while文