JavaScriptでのfor…of文を用いたループ処理の5つの基本

JavaScriptのfor...of文を使ったループ処理の基本JS
この記事は約12分で読めます。

 

【サイト内のコードはご自由に個人利用・商用利用いただけます】

この記事では、プログラムの基礎知識を前提に話を進めています。

説明のためのコードや、サンプルコードもありますので、もちろん初心者でも理解できるように表現してあります。

基本的な知識があればカスタムコードを使って機能追加、目的を達成できるように作ってあります。

※この記事は、一般的にプロフェッショナルの指標とされる『実務経験10,000時間以上』を凌駕する現役のプログラマチームによって監修されています。

サイト内のコードを共有する場合は、参照元として引用して下さいますと幸いです

※Japanシーモアは、常に解説内容のわかりやすさや記事の品質に注力しております。不具合、分かりにくい説明や不適切な表現、動かないコードなど気になることがございましたら、記事の品質向上の為にお問い合わせフォームにてご共有いただけますと幸いです。
(送信された情報は、プライバシーポリシーのもと、厳正に取扱い、処分させていただきます。)

●for…of文の基本的な使い方

JavaScriptのfor…of文は、ES2015で導入された比較的新しいループ構文です。

配列やイテラブルオブジェクトを簡潔に反復処理できるため、コードの可読性が向上し、バグが発生しにくくなります。

for…of文を使いこなせるようになれば、JavaScriptのコーディングスキルが飛躍的に向上するでしょう。

○配列の反復処理

for…of文を使えば、配列の要素を1つずつ取り出して処理することができます。

従来のforループと比べて、インデックスを意識する必要がないため、コードがスッキリとします。

○サンプルコード1:配列の要素を順に出力する

const fruits = ['apple', 'banana', 'orange'];

for (const fruit of fruits) {
  console.log(fruit);
}

実行結果

apple
banana
orange

このコードでは、fruitsという配列の要素を1つずつfruitという変数に代入し、console.logを使って出力しています。

シンプルで読みやすいコードになっていることがわかりますね。

○文字列の反復処理

for…of文は、文字列に対しても使用できます。

文字列を1文字ずつ取り出して処理する際に便利です。

○サンプルコード2:文字列の文字を順に出力する

const message = 'Hello, World!';

for (const char of message) {
  console.log(char);
}

実行結果

H
e
l
l
o
,

W
o
r
l
d
!

このコードでは、messageという文字列の各文字を1つずつcharという変数に代入し、console.logを使って出力しています。

文字列をイテラブルオブジェクトとして扱えるため、for…of文との相性が抜群です。

for…of文を使えば、配列や文字列の反復処理がシンプルに書けることがわかりましたね。

次は、ループ処理の中でインデックスを取得する方法について見ていきましょう。

●for…of文でインデックスを取得する方法

先ほどは、for…of文を使って配列や文字列の反復処理を行う方法を見てきました。

でも、ループ処理の中で現在の要素のインデックスを知りたいこともありますよね。

従来のforループではインデックスを直接扱えましたが、for…of文ではどうすればいいのでしょうか。

ちょっとややこしいですが、一緒に解決策を見つけていきましょう。

○Arrayオブジェクトのentriesメソッドを使う

実は、Arrayオブジェクトにはentriesというメソッドがあります。

これを使うと、配列の各要素とそのインデックスを組み合わせたイテレータを取得できるんです。

ちょっとわかりにくい部分もあると思うので、サンプルコードを見ながら理解を深めていきましょう。

○サンプルコード3:配列の要素とインデックスを取得する

const fruits = ['apple', 'banana', 'orange'];

for (const [index, fruit] of fruits.entries()) {
  console.log(`${index}: ${fruit}`);
}

実行結果

0: apple
1: banana
2: orange

このコードでは、fruits配列に対してentriesメソッドを呼び出し、取得したイテレータをfor…of文で反復処理しています。

各ループでは、分割代入を使ってインデックスと要素を別々の変数に代入しています。

こんな感じで、for…of文でもインデックスを取得することができます。

○TypeScriptでインデックスを取得する

TypeScriptを使っている場合は、もう少し型安全な方法でインデックスを取得することができます。

せっかくなので、TypeScriptでの例も見てみましょう。

○サンプルコード4:TypeScriptでインデックスを取得する例

const fruits: string[] = ['apple', 'banana', 'orange'];

for (const [index, fruit] of fruits.entries()) {
  console.log(`${index}: ${fruit}`);
}

実行結果

0: apple
1: banana
2: orange

TypeScriptでは、配列の型を明示的に指定することができます。

このコードでは、fruits配列の型をstring[]と指定しています。

あとの処理は先ほどのJavaScriptの例と同じですが、型安全性が向上しているのがポイントです。

●for…of文でループを中断する

先ほどまでは、for…of文を使って配列やイテラブルオブジェクトの反復処理を行う方法やインデックスを取得する方法について見てきました。

でも、実際のプログラミングでは、特定の条件が満たされたときにループを中断したいこともありますよね。

そんなときはどうすればいいのでしょうか。

for…of文でもループを途中で中断する方法があるんですね。

○breakキーワードを使ってループを抜ける

ループを途中で中断するには、breakキーワードを使います。

breakキーワードは、現在のループを即座に終了し、ループの次の文から処理を再開します。

ちょっとわかりにくい部分もあると思うので、サンプルコードを見ながら理解を深めていきましょう。

○サンプルコード5:特定の条件でループを中断する

const numbers = [1, 2, 3, 4, 5];

for (const number of numbers) {
  if (number === 3) {
    console.log('ループを中断します');
    break;
  }
  console.log(number);
}
console.log('ループ終了後の処理');

実行結果

1
2
ループを中断します
ループ終了後の処理

このコードでは、numbers配列を反復処理しながら、各要素の値を出力しています。

ただし、要素の値が3の場合は、「ループを中断します」というメッセージを出力し、breakキーワードを使ってループを中断しています。

その結果、3以降の要素は処理されず、すぐにループ終了後の処理に移ります。

○continueキーワードを使ってスキップする

breakキーワードがループを完全に中断するのに対し、continueキーワードは現在の反復処理をスキップし、次の反復処理に進みます。

つまり、特定の条件を満たす場合に処理を飛ばすことができるんです。

○サンプルコード6:特定の条件で処理をスキップする

const numbers = [1, 2, 3, 4, 5];

for (const number of numbers) {
  if (number === 3) {
    console.log('この反復処理をスキップします');
    continue;
  }
  console.log(number);
}

実行結果

1
2
この反復処理をスキップします
4
5

このコードでは、要素の値が3の場合に、「この反復処理をスキップします」というメッセージを出力し、continueキーワードを使って現在の反復処理をスキップしています。

その結果、3だけが処理されずに飛ばされ、他の要素は通常通り処理されます。

●for…of文と連想配列

先ほどまでは、for…of文を使って配列やイテラブルオブジェクトの反復処理を行う方法や、ループの中断方法について見てきました。

でも、実際のプログラミングでは、連想配列(オブジェクト)を扱うことも多いですよね。

そんなときにfor…of文は使えるのでしょうか。連想配列とfor…of文の関係について、一緒に探っていきましょう。

○Object.entriesメソッドで連想配列を反復処理

実は、連想配列自体はイテラブルではないため、直接for…of文で反復処理することはできません。でも、安心してください。

Object.entriesメソッドを使えば、連想配列のキーと値のペアを配列として取得できるんです。

その配列をfor…of文で反復処理すれば、連想配列の要素にアクセスできます。

ちょっとややこしいですが、サンプルコードを見ながら理解を深めていきましょう。

○サンプルコード7:連想配列のキーと値を取得する

const person = {
  name: '山田太郎',
  age: 30,
  gender: '男性'
};

for (const [key, value] of Object.entries(person)) {
  console.log(`${key}: ${value}`);
}

実行結果

name: 山田太郎
age: 30
gender: 男性

このコードでは、personという連想配列に対してObject.entriesメソッドを呼び出し、キーと値のペアを配列として取得しています。

その配列をfor…of文で反復処理し、分割代入を使ってキーと値を別々の変数に代入しています。

こんな感じで、連想配列の要素に簡単にアクセスできるんです。

○Object.keysとObject.valuesメソッドの活用

連想配列のキーや値だけを取得したい場合は、Object.keysメソッドやObject.valuesメソッドを使うのも便利です。

Object.keysメソッドは連想配列のキーを配列として返し、Object.valuesメソッドは連想配列の値を配列として返します。

これらの配列をfor…of文で反復処理すれば、キーや値だけを簡単に取得できます。

○サンプルコード8:キーまたは値のみを取得する

const person = {
  name: '山田太郎',
  age: 30,
  gender: '男性'
};

console.log('キーのみ:');
for (const key of Object.keys(person)) {
  console.log(key);
}

console.log('値のみ:');
for (const value of Object.values(person)) {
  console.log(value);
}

実行結果

キーのみ:
name
age
gender
値のみ:
山田太郎
30
男性

このコードでは、Object.keysメソッドとObject.valuesメソッドを使って、personという連想配列のキーと値をそれぞれ配列として取得しています。

そして、それらの配列をfor…of文で反復処理し、キーや値を個別に出力しています。

状況に応じて適切なメソッドを選択することで、連想配列の要素を柔軟に扱うことができます。

●for…of文とfor…in文の違い

先ほどまでは、for…of文を使ったループ処理の様々な側面について見てきました。

でも、JavaScriptにはfor…in文というループ構文もありますよね。

初心者のうちは、この2つの構文の違いがよくわからないという人も多いのではないでしょうか。

ここでは、for…of文とfor…in文の違いについて、詳しく見ていきましょう。

○for…in文の注意点と非推奨の理由

for…in文は、オブジェクトのプロパティを列挙するために使用されます。

ただし、for…in文にはいくつかの注意点があります。

まず、for…in文では、オブジェクトの継承されたプロパティも列挙されてしまうことです。

これにより、意図しないプロパティが反復処理に含まれる可能性があります。

また、for…in文では、プロパティの列挙順序が保証されません。

つまり、オブジェクトのプロパティがどのような順序で処理されるかは予測できないのです。

これらの理由から、for…in文は配列の反復処理には適しておらず、非推奨とされています。

○パフォーマンスとセキュリティの観点から

for…in文には、パフォーマンスとセキュリティの面でも問題があります。

オブジェクトのプロパティを列挙する処理は、for…of文と比べて遅くなる傾向があります。

特に、大きなオブジェクトを扱う場合は、パフォーマンスの低下が顕著になることがあります。

セキュリティの観点からも、for…in文は注意が必要です。

悪意のあるコードが、オブジェクトのプロトタイプに予期しないプロパティを追加する可能性があるからです。

そうなると、for…in文でそれらのプロパティが列挙されてしまい、セキュリティ上の問題につながるかもしれません。

○for…of文が推奨される背景

一方、for…of文は、イテラブルオブジェクトの値を直接取得するために設計されています。

配列や文字列など、組み込みのイテラブルオブジェクトとの相性が抜群です。

for…of文は、シンプルで直感的な構文を持ち、コードの可読性を高めてくれます。

また、for…of文は、カスタムイテラブルオブジェクトにも対応しています。

これにより、独自のオブジェクトを反復処理に適した形で実装できるようになります。

パフォーマンスとセキュリティの面でも、for…of文はfor…in文よりも優れているとされています。

こうした背景から、モダンなJavaScriptではfor…of文の使用が推奨されているのです。

特に配列の反復処理には、for…of文を使うのが一般的です。

オブジェクトのプロパティを列挙する必要がある場合は、Object.keys()やObject.entries()を使って配列に変換してから、for…of文で処理するのがよいでしょう。

まとめ

今回は、JavaScriptのfor…of文を使ったループ処理について、基本的な使い方からより応用的な内容まで詳しく解説してきました。

配列や文字列などのイテラブルオブジェクトを簡潔に反復処理できるfor…of文は、モダンなJavaScriptでは欠かせない構文です。

インデックスの取得やループの中断、連想配列への応用など、様々なテクニックを身につけることで、より効率的で可読性の高いコードが書けるようになるでしょう。

また、for…of文とfor…in文の違いを理解し、適切な使い分けができるようになることも重要です。

今回学んだ内容を活かして、JavaScriptのループ処理に自信を持ってチャレンジしてみてください。

きっと、コーディングの幅が広がるはずです。