基礎

JavaScriptのfor文入門|繰り返し処理の基本とfor...of・for...inの使い分け

JavaScriptの for 文は、指定した回数だけ処理を繰り返す最も基本的なループ構文です。初期化、条件、更新の3つの式を1行にまとめて記述できるため、カウンター変数を使ったループに最適です。

この記事では、基本の for 文に加え、配列向けの for...of、オブジェクト向けの for...in の使い方と使い分けを、実践的なコード例で解説します。

基本的な使い方

for 文は、初期化式、条件式、更新式の3つの部分で構成されます。セミコロンで区切って1行に記述します。

JavaScript
// 基本のfor文
for (let i = 0; i < 5; i++) {
  console.log(i + '回目');
}

// 逆順ループ
for (let i = 5; i > 0; i--) {
  console.log('カウントダウン: ' + i);
}

// 2ずつ増加
for (let i = 0; i <= 10; i += 2) {
  console.log(i);
}
実行結果
0回目
1回目
2回目
3回目
4回目
カウントダウン: 5
カウントダウン: 4
カウントダウン: 3
カウントダウン: 2
カウントダウン: 1
0
2
4
6
8
10

for (let i = 0; i < 5; i++) は「i を0で初期化し、i が5未満の間、i を1ずつ増やしながら繰り返す」という意味です。let で宣言した i はループ内でのみ有効で、ループ終了後は参照できません。

配列のループ

配列をループする方法は複数ありますが、目的に応じて使い分けることで、読みやすいコードになります。

JavaScript
const fruits = ['りんご', 'バナナ', 'オレンジ', 'ぶどう'];

// 従来のfor文(インデックスが必要な場合)
for (let i = 0; i < fruits.length; i++) {
  console.log(i + ': ' + fruits[i]);
}

// for...of文(値だけ必要な場合)
console.log('--- for...of ---');
for (const fruit of fruits) {
  console.log(fruit);
}

// for...ofでインデックスも取得(entries())
console.log('--- entries ---');
for (const [index, fruit] of fruits.entries()) {
  console.log(index + ': ' + fruit);
}
実行結果
0: りんご
1: バナナ
2: オレンジ
3: ぶどう
--- for...of ---
りんご
バナナ
オレンジ
ぶどう
--- entries ---
0: りんご
1: バナナ
2: オレンジ
3: ぶどう

for...of 文はES6で追加された構文で、配列の要素を直接取り出せます。インデックスが不要な場合は for...of を使うとシンプルに書けます。インデックスも必要な場合は .entries() と分割代入を組み合わせるか、従来の for 文を使います。

for...in文(オブジェクトのループ)

JavaScript
const user = {
  name: '田中',
  age: 28,
  city: '東京',
  job: 'エンジニア'
};

// for...inでオブジェクトのキーをループ
for (const key in user) {
  console.log(key + ': ' + user[key]);
}
実行結果
name: 田中
age: 28
city: 東京
job: エンジニア

for...in はオブジェクトのプロパティ名(キー)を列挙します。配列にも使えますが、プロトタイプチェーン上のプロパティも列挙される可能性があるため、配列には for...offorEach を使うのが推奨されます。

実践例:ネストしたループと九九の表

JavaScript
// 九九の表
for (let i = 1; i <= 9; i++) {
  let row = '';
  for (let j = 1; j <= 9; j++) {
    const product = (i * j).toString().padStart(3, ' ');
    row += product;
  }
  console.log(row);
}

// 配列のフラット化
const matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
const flat = [];
for (const row of matrix) {
  for (const num of row) {
    flat.push(num);
  }
}
console.log('フラット化:', flat);
実行結果
  1  2  3  4  5  6  7  8  9
  2  4  6  8 10 12 14 16 18
  3  6  9 12 15 18 21 24 27
  4  8 12 16 20 24 28 32 36
  5 10 15 20 25 30 35 40 45
  6 12 18 24 30 36 42 48 54
  7 14 21 28 35 42 49 56 63
  8 16 24 32 40 48 56 64 72
  9 18 27 36 45 54 63 72 81
フラット化: [1, 2, 3, 4, 5, 6, 7, 8, 9]
for...of vs forEach

for...offorEach はどちらも配列のループに使えますが、for...ofbreak でループを中断できる一方、forEach は中断できません。途中で抜ける可能性がある場合は for...of、全要素を処理する場合は forEach が適しています。

for...in を配列に使わない

for...in を配列に使うと、インデックスが数値ではなく文字列になり、プロトタイプ上のプロパティも列挙される可能性があります。配列のループには必ず forfor...of、または forEach を使いましょう。

まとめ

  • for 文は初期化・条件・更新を1行に記述し、回数指定のループに最適
  • for...of は配列の要素を直接取り出せるES6構文で、break も使える
  • for...in はオブジェクトのキーを列挙するため、配列には使わない
  • インデックスが必要なら従来の for 文か entries() を使う
  • ネストしたループでは内側のループが外側の1回ごとに全回実行される