Our volunteers haven't translated this article into عربي yet. Join us and help get the job done!
You can also read the article in English (US).

The for...of statement creates a loop iterating over iterable objects (including Array, Map, Set, String, TypedArray, arguments object and so on), invoking a custom iteration hook with statements to be executed for the value of each distinct property.

Syntax

for (variable of iterable) {
  statement
}
variable
On each iteration a value of a different property is assigned to variable.
iterable
Object whose enumerable properties are iterated.

Examples

Iterating over an Array

let iterable = [10, 20, 30];

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

You can use const instead of let too, if you don't reassign the variable inside the block.

let iterable = [10, 20, 30];

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

Iterating over a String

let iterable = 'boo';

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

Iterating over a TypedArray

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

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

Iterating over a 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

Iterating over a Set

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

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

Iterating over arguments object

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

// 1
// 2
// 3

Iterating over a DOM collection

Iterating over DOM collections like NodeList: the following example adds a read class to paragraphs that are direct descendants of an article:

// Note: This will only work in platforms that have
// implemented NodeList.prototype[Symbol.iterator]
let articleParagraphs = document.querySelectorAll('article > p');

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

Closing iterators

In for...of loops, abrupt iteration termination can be caused by break, continue[4], throw or return[5]. In these cases, the iterator is closed.

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

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

Iterating over generators

You can also iterate over generators:

function* fibonacci() { // a generator function
  let [prev, curr] = [0, 1];
  while (true) {
    [prev, curr] = [curr, prev + curr];
    yield curr;
  }
}

for (let n of fibonacci()) {
  console.log(n);
  // truncate the sequence at 1000
  if (n >= 1000) {
    break;
  }
}

Do not reuse generators

Generators should not be re-used, even if the for...of loop is terminated early, for example via the break keyword. Upon exiting a loop, the generator is closed and trying to iterate over it again does not yield any further results.

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.
}

Iterating over other iterable objects

You can also iterate over an object that explicitly implements iterable protocol:

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

Difference between for...of and for...in

Both for...in and for...of statements iterate over something. The main difference between them is in what they iterate over.

The for...in statement iterates over the enumerable properties of an object, in original insertion order.

The for...of statement iterates over data that iterable object defines to be iterated over.

The following example shows the difference between a for...of loop and a for...in loop when used with an Array.

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';

Every object will inherit objCustom property and every object that is an Array will inherit arrCustom property because of adding those properties to Object.prototype and Array.prototype. The object iterable inherits properties objCustom and arrCustom because of inheritance and the prototype chain.

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

This loop logs only enumerable properties of iterable object, in original insertion order. It doesn't log array elements 3, 5, 7 or hello because those are not enumerable properties. But it logs array indexes as well as arrCustom and objCustom, which are. If you're not sure why the properties are iterated over, there's a more thorough explanation of how array iteration and for...in work.

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

This loop is similar to the first one, but it uses hasOwnProperty() to check, if the found enumerable property is object's own (not inherited). And if it is, the property is logged. Properties 0, 1, 2 and foo are logged because they are own properties (not inherited). Properties arrCustom and objCustom are not logged because they are inherited.

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

This loop iterates and logs values that iterable as an iterable object defines to be iterated over, which are array elements 3, 5, 7 and not any of object's properties.

Specifications

Specification Status Comment
ECMAScript 2015 (6th Edition, ECMA-262)
The definition of 'for...of statement' in that specification.
Standard Initial definition.
ECMAScript Latest Draft (ECMA-262)
The definition of 'for...of statement' in that specification.
Living Standard  

Browser compatibility

FeatureChromeEdgeFirefoxInternet ExplorerOperaSafari
Basic Support3812131 No257.1
Closing iterators51 (Yes)53 No (Yes) (Yes)
FeatureAndroidChrome for AndroidEdge mobileFirefox for AndroidIE mobileOpera AndroidiOS Safari
Basic Support5.1 (Yes)12 (Yes) No258
Closing iterators (Yes) (Yes) (Yes)53 No (Yes) (Yes)

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

See also