定義と使用方法
for...of
文は値(value)で反復処理できるオブジェクトのためのループ文です。
値(value)で反復処理できるオブジェクトであれば、どのようなオブジェクトでもfor...of
文で処理することができます。つまり、オブジェクトから取り出した値(value)を基に動作するループを実行します。
値(value)で反復処理できるオブジェクトには、次のようなものがあります。
- 配列、文字列、
Map
、Set
など、Iteration Protocolsが適用されたオブジェクト - DOMを扱うコレクションであるHTMLCollectionおよびNodeListオブジェクト
arguments
などの一部の擬似配列オブジェクト- Iteration Protocolsが適用されたユーザー定義オブジェクト
以前は配列、オブジェクト、文字列など、種類ごとに異なるループの書き方をする必要がありました。for...of
文はこのような不便さを解消し、値(value)で反復処理できるオブジェクトであれば一貫して適用できるループ構文です。
注意してください!
オブジェクトリテラルなどで作成した一般的なオブジェクト(plain objects)は、値(value)で反復処理することはできません。for...of
文の代わりに、オブジェクトのプロパティ(key)を反復処理するfor...in
文を使用して処理することができます。
基本の例
次に、値(value)で反復処理できる代表的な配列オブジェクトをfor...of
文で反復処理する例を示します。
const iterable = [1, 2, 3, 4, 5]; // 配列を例として使用
for (const item of iterable) {
console.log(item);
}
1 2 3 4 5
構文
for (variable of iterable) {
// 繰り返し処理するコード
}
variable
:ループ内で現在反復処理中の値(value)を格納する変数の名前です。iterable
:反復処理したい値(value)で順に巡回できるオブジェクトです
さまざまな例:オブジェクトごとの反復処理
次に、値(value)で反復処理できる代表的なオブジェクトごとにfor...of
文で反復処理する例を示します。
配列(Array)
const arr = ["apple", "banana", "cherry"];
for (const fruit of arr) {
console.log(fruit);
}
// 出力: "apple" "banana" "cherry"
文字列(String)
const str = "abc";
for (const char of str) {
console.log(char);
}
// 出力: "a" "b" "c"
Map
const map = new Map([["key1", "value1"], ["key2", "value2"]]);
for (const [key, value] of map) {
console.log(key, value);
}
// 出力: "key1 value1" "key2 value2"
Set
const set = new Set([1, 2, 3]);
for (const value of set) {
console.log(value);
}
// 出力: 1 2 3
HTMLCollection
<ul>
<li>うどん</li>
<li>ラーメン</li>
<li>おにぎり</li>
</ul>
const liElements = document.getElementsByTagName("li"); // liタグをすべて選択
console.log(liElements); // HTMLCollection(3) [li, li, li]
/* for...of文の適用 */
for (const liElement of liElements) {
console.log(liElement.textContent);
}
// 出力: "うどん" "ラーメン" "おにぎり"
NodeList
<ul>
<li>うどん</li>
<li>ラーメン</li>
<li>おにぎり</li>
</ul>
const liElements = document.querySelectorAll("li"); // liセレクタをすべて選択
console.log(liElements); // NodeList(3) [li, li, li]
/* for...of文の適用 */
for (const liElement of liElements) {
console.log(liElement.textContent);
}
// 出力: "うどん" "ラーメン" "おにぎり"
コード補足説明
querySelectorAll()で返されるNodeListオブジェクトは、擬似配列オブジェクトであり、かつIteration Protocolsが適用されたイテラブルオブジェクトです。
arguments
function showArgs() {
for (const arg of arguments) {
console.log(arg);
}
}
showArgs(10, 20, 30);
// 出力: 10 20 30
break
、continue
文とともに使用
for...of
文でも、ループの制御のためにbreak
文やcontinue
文を使用することができます。次の例では、条件に応じてループを終了したりスキップしたりする方法を示します。
/* breakの例:3以上の場合にループを終了 */
const numbers = [1, 2, 3, 4, 5];
for (const num of numbers) {
if (num >= 3) break;
console.log(num);
}
// 出力: 1 2
/* continueの例:3の場合はスキップ */
for (const num of numbers) {
if (num === 3) continue;
console.log(num);
}
// 出力: 1 2 4 5
注意点
for...of
文は、値(value)で反復処理できるオブジェクトのためのループ文です。
つまり、オブジェクトから取り出した値を基に動作するループを実行するということです。この点は便利ですが、一方でいくつかの制約もあります。これを理解して使用することで、不必要なエラーや混乱を避けることができます。
インデックスに直接アクセスできない
for...of
文は、反復処理するオブジェクトの現在の値(value)のみを提供します。インデックス(index)は直接提供されません。
const numbers = [10, 20, 30];
// 値だけを反復処理
for (const value of numbers) {
console.log(value); // 10, 20, 30
}
一般的なオブジェクトでは使用できません
オブジェクトリテラルなどで作成した一般的なオブジェクト(plain objects)は、値(value)で反復処理することはできません。for...of
文の代わりに、オブジェクトのプロパティ(key)を反復処理するfor...in
文を使用して処理することができます。
const obj = {
a: 1,
b: 2
}
// エラー発生!
for (const value of obj) {
console.log(value);
}
// TypeError: obj is not iterable
一般的なオブジェクトもfor...of
文で反復処理するには、Object.keys()
、Object.values()
、Object.entries()
などのメソッドを使用して順に処理する必要があります。
const obj = {
a: 1,
b: 2
}
// キーの反復処理
for (const key of Object.keys(obj)) {
console.log(key); // a, b
}
// 値の反復処理
for (const value of Object.values(obj)) {
console.log(value); // 1, 2
}
// キーと値の両方を反復処理
for (const [key, value] of Object.entries(obj)) {
console.log(key, value); // a 1, b 2
}
仕様書
仕様書 | |
---|---|
for...of
|
ECMAScript Language Specification #sec-for-in-and-for-of-statements |
ブラウザ互換性
文 |
デスクトップ Chrome
|
デスクトップデスクトップ Edge
|
デスクトップ Firefox
|
Safari
|
---|---|---|---|---|
for...of
|
38 | 12 | 13 | 7 |