for...ofは、iterableオブジェクトに対して反復的な処理をするループを作成します(iterableオブジェクトには組み込みのString, Array, 例えば Array に似たargumentsNodeListオブジェクト、TypedArray, Map, Set, ユーザー定義のiterableなどが含まれます)。iterableオブジェクトの個々のプロパティに対して文を実行しさまざまな処理を行うことができます。

構文

for (variable of iterable) {
  statement
}
variable
それぞれの反復処理において、別々のプロパティの値が variable に代入されます。
iterable
列挙可能なプロパティに対して、反復処理を行うオブジェクトです。

Array で反復する:

let iterable = [10, 20, 30];

for (let value of iterable) {
  value += 1;
  console.log(value);
}
// 11
// 21
// 31

ブロック内で変数を修正したくない場合、let の代わりに const を使用できます。

let iterable = [10, 20, 30];

for (const value of iterable) {
  console.log(value);
}
// 10
// 20
// 30

String で反復する:

let iterable = "boo";

for (let value of iterable) {
  console.log(value);
}
// "b"
// "o"
// "o"

TypedArray で反復する:

let iterable = new Uint8Array([0x00, 0xff]);

for (let value of iterable) {
  console.log(value);
}
// 0
// 255

Map で反復する:

let iterable = new Map([["a", 1], ["b", 2], ["c", 3]]);

for (let entry of iterable) {
  console.log(entry);
}
// [a, 1]
// [b, 2]
// [c, 3]

for (let [key, value] of iterable) {
  console.log(value);
}
// 1
// 2
// 3

Set で反復する:

let iterable = new Set([1, 1, 2, 2, 3, 3]);

for (let value of iterable) {
  console.log(value);
}
// 1
// 2
// 3

arguments オブジェクトで反復する

(function() {
  for (let argument of arguments) {
    console.log(argument);
  }
})(1, 2, 3);

// 1
// 2
// 3

DOM コレクションで反復する

NodeList のような DOM コレクションで反復する場合、次の例は read クラスを article の直系の子孫である段落(p)に加えます:

// 注:特定のプラットホームでのみ動作します
// implemented NodeList.prototype[Symbol.iterator]
let articleParagraphs = document.querySelectorAll("article > p");

for (let paragraph of articleParagraphs) {
  paragraph.classList.add("read");
}

iteratorsを閉じる

for...of ループでは、break, continue[4], throw or return[5]によってイテレーションが終了されます。この場合、イテレータは閉じられます。

function* foo(){ 
  yield 1; 
  yield 2; 
  yield 3; 
}; 

for (let o of foo()) { 
  console.log(o); 
  break; // closes iterator, triggers return
}

ジェネレーターで反復する

ジェネレーター(function* で反復することもできます:

function* fibonacci() { // ジェネレーター関数
  let [prev, curr] = [1, 1];
  while (true) {
    [prev, curr] = [curr, prev + curr];
    yield curr;
  }
}

for (let n of fibonacci()) {
  console.log(n);
  // 1000でシーケンスを打ち切る
  if (n >= 1000) {
    break;
  }
}

ジェネレーターは再利用しないで

ジェネレーターは、for...of が早く終了しても (例えば break キーワードで) 再利用してはいけません。ループを抜けると、ジェネレーターは閉じられて、そこで繰り返してもそれ以上の結果は算出されません。

var gen = (function *(){
  yield 1;
  yield 2;
  yield 3;
})();
for (let o of gen) {
  console.log(o);
  break;  // Closes iterator
}

// The generator should not be re-used, the following does not make sense!
for (let o of gen) {
  console.log(o); // Never called.
}

反復可能オブジェクトで反復する

明示的に iterable プロトコルを実装しているオブジェクトを反復することもできます:

var iterable = {
  [Symbol.iterator]() {
    return {
      i: 0,
      next() {
        if (this.i < 3) {
          return { value: this.i++, done: false };
        }
        return { value: undefined, done: true };
      }
    };
  }
};

for (var value of iterable) {
  console.log(value);
}
// 0
// 1
// 2

for...offor...in との違い

for...infor...of 文は、両方とも何かに対する繰り返しです。これらの主な違いは何に対する繰り返しなのかというところです。

for...in ループは、オブジェクトのすべての enumerable なプロパティを反復します。

for...of 構文は、全オブジェクトというよりコレクションに特有なものです。これは、[Symbol.iterator] プロパティを持つ任意のコレクションの要素全体をこの方法で反復します。

次の例に、for...of ループと for...in ループの違いを示します。

Object.prototype.objCustom = function() {}; 
Array.prototype.arrCustom = function() {};

let iterable = [3, 5, 7];
iterable.foo = 'hello';

for (let i in iterable) {
  console.log(i); // logs 0, 1, 2, "foo", "arrCustom", "objCustom"
}

for (let i in iterable) {
  if (iterable.hasOwnProperty(i)) {
    console.log(i); // logs 0, 1, 2, "foo"
  }
}

for (let i of iterable) {
  console.log(i); // logs 3, 5, 7
}

上のコードを一歩一歩見ていきましょう。

Object.prototype.objCustom = function() {};
Array.prototype.arrCustom = function() {}; 

let iterable = [3, 5, 7]; 
iterable.foo = 'hello';

すべてのオブジェクトは objCustom プロパティを継承していて、Array 内のすべてのオブジェクトは arrCustom プロパティを継承し、その理由は Object.prototypeArray.prototype にこのプロパティを追加しているためです。この iterable オブジェクトは objCustomarrCustom プロパティを継承し、その理由は継承とプロトタイプチェーンのためです。

for (let i in iterable) {
  console.log(i); // logs 0, 1, 2, "foo", "arrCustom", "objCustom" 
}

このループはiterable オブジェクトの enumerable プロパティだけを、元々の挿入順で出力します。配列要素 3, 5, 7hello は出力せず、これはこれらがenumerable プロパティではないためです。しかし配列のインデックスarrCustomobjCustomと同様に出力します。なぜプロパティが繰り返しに出てこないか不明な場合は array iteration and for...in にもっと詳しい説明があります。

for (let i in iterable) {
  if (iterable.hasOwnProperty(i)) {
    console.log(i); // logs 0, 1, 2, "foo"
  }
}

このループは最初のぶんと似ていますが、見つかったenumerable プロパティが(継承されたものでなく)オブジェクト自身のものかどうかチェックするのにhasOwnProperty() を使っています。そして、その場合、プロパティは出力されます。0, 1, 2foo は自身のプロパティ (継承されたものでない)ために出力されます。arrCustomobjCustom継承されたものであるために出力されません。

for (let i of iterable) {
  console.log(i); // logs 3, 5, 7 
}

このループは、 iterableiterable オブジェクト として反復処理されるように定義した値を反復して出力します。これらの値は配列の要素3,5,7であり、オブジェクトのプロパティではありません。

仕様

仕様 ステータス コメント
ECMAScript 2015 (6th Edition, ECMA-262)
for...of statement の定義
標準 初期定義。
ECMAScript Latest Draft (ECMA-262)
for...of statement の定義
ドラフト  

ブラウザー互換性

機能ChromeEdgeFirefoxInternet ExplorerOperaSafari
基本対応3812131 なし258
Closing iterators51 あり53 なし あり あり
機能Android webviewChrome for AndroidEdge mobileFirefox for AndroidOpera AndroidiOS SafariSamsung Internet
基本対応5.1 あり12141258 あり
Closing iterators あり あり あり53 あり あり あり

1. Prior to Firefox 51, using the for...of loop construct with the const keyword threw a SyntaxError ("missing = in const declaration").

関連情報

ドキュメントのタグと貢献者

最終更新者: taiyaki32lp64,