Please note, this is a STATIC archive of website developer.mozilla.org from 03 Nov 2016, cach3.com does not collect or store any user information, there is no "phishing" involved.

Revision 1107093 of for...of

  • Revision slug: Web/JavaScript/Reference/Statements/for...of
  • Revision title: for...of
  • Revision id: 1107093
  • Created:
  • Creator: fscholz
  • Is current revision? No
  • Comment bug 1286965

Revision Content

{{jsSidebar("Statements")}}

The for...of statement creates a loop iterating over iterable objects (including {{jsxref("Array")}}, {{jsxref("Map")}}, {{jsxref("Set")}}, {{jsxref("String")}}, {{jsxref("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 {{jsxref("Array")}}:

let iterable = [10, 20, 30];

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

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

let iterable = [10, 20, 30];

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

Iterating over a {{jsxref("String")}}:

let iterable = "boo";

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

Iterating over a {{jsxref("TypedArray")}}:

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

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

Iterating over a {{jsxref("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 {{jsxref("Set")}}:

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

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

Iterating over a DOM collection

Iterating over DOM collections like {{domxref("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");
}

Iterating over generators

You can also iterate over generators:

function* fibonacci() { // a generator function
  let [prev, curr] = [1, 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;
  }
}

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

The for...in loop will iterate over all enumerable properties of an object.

The for...of syntax is specific to collections, rather than all objects. It will iterate in this manner over the elements of any collection that has a [Symbol.iterator] property.

The following example shows the difference between a for...of loop and a for...in loop.

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 of iterable) {
  console.log(i); // logs 3, 5, 7
}

Specifications

Specification Status Comment
{{SpecName('ES6', '#sec-for-in-and-for-of-statements', 'for...of statement')}} {{Spec2('ES6')}} Initial definition.
{{SpecName('ESDraft', '#sec-for-in-and-for-of-statements', 'for...of statement')}} {{Spec2('ESDraft')}}  

Browser compatibility

{{CompatibilityTable}}

Feature Chrome Firefox (Gecko) Edge Opera Safari
Basic support {{CompatChrome(38)}} [1]
{{CompatChrome(51)}} [3]
{{CompatGeckoDesktop("13")}} [2] 12 25 7.1
Feature Android Chrome for Android Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile
Basic support 5.1 {{CompatChrome(38)}} [1] {{CompatGeckoMobile("13")}} [2] {{CompatNo}} {{CompatUnknown}} 8

[1] From Chrome 29 to Chrome 37 this feature was available behind a preference. In chrome://flags/#enable-javascript-harmony, activate the entry “Enable Experimental JavaScript”.

[2] From Gecko 17 (Firefox 17 / Thunderbird 17 / SeaMonkey 2.14) to Gecko 26 (Firefox 26 / Thunderbird 26 / SeaMonkey 2.23 / Firefox OS 1.2) the iterator property was used (bug 907077), and from Gecko 27 to Gecko 35 the "@@iterator" placeholder was used. In Gecko 36 (Firefox 36 / Thunderbird 36 / SeaMonkey 2.33), the @@iterator symbol got implemented (bug 918828).

[3] Support for iteration of objects was added in Chrome 51.

See also

  • for each...in - a similar statement, but iterates over the values of object's properties, rather than the property names themselves (deprecated).
  • {{jsxref("Array.prototype.forEach()")}}
  • Map.prototype.forEach()

Revision Source

<div>{{jsSidebar("Statements")}}</div>

<p>The <strong><code>for...of</code> statement </strong>creates a loop iterating over <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols#iterable">iterable objects</a> (including {{jsxref("Array")}}, {{jsxref("Map")}}, {{jsxref("Set")}}, {{jsxref("String")}}, {{jsxref("TypedArray")}}, <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions_and_function_scope/arguments">arguments</a> object and so on), invoking a custom iteration hook with statements to be executed for the value of each distinct property.</p>

<h2 id="Syntax">Syntax</h2>

<pre class="syntaxbox">
for (<em>variable</em> of <em>iterable</em>) {
  <em>statement
</em>}
</pre>

<dl>
 <dt><code>variable</code></dt>
 <dd>On each iteration a value of a different property is assigned to <em>variable</em>.</dd>
 <dt><code>iterable</code></dt>
 <dd>Object whose enumerable properties are iterated.</dd>
</dl>

<h2 id="Examples">Examples</h2>

<h3 id="Iterating_over_an_jsxref(Array)">Iterating over an {{jsxref("Array")}}:</h3>

<pre class="brush:js">
let iterable = [10, 20, 30];

for (let value of iterable) {
  console.log(value);
}
// 10
// 20
// 30
</pre>

<p>You can use <a href="/en-US/docs/Web/JavaScript/Reference/Statements/const"><code>const</code></a> instead of <a href="/en-US/docs/Web/JavaScript/Reference/Statements/let"><code>let</code></a> too, if you don't modify the variable inside the block.</p>

<pre class="brush:js">
let iterable = [10, 20, 30];

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

<h3 id="Iterating_over_a_jsxref(String)">Iterating over a {{jsxref("String")}}:</h3>

<pre class="brush:js">
let iterable = "boo";

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

<h3 id="Iterating_over_a_jsxref(TypedArray)">Iterating over a {{jsxref("TypedArray")}}:</h3>

<pre class="brush:js">
let iterable = new Uint8Array([0x00, 0xff]);

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

<h3 id="Iterating_over_a_jsxref(Map)">Iterating over a {{jsxref("Map")}}:</h3>

<pre class="brush:js">
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
</pre>

<h3 id="Iterating_over_a_jsxref(Set)">Iterating over a {{jsxref("Set")}}:</h3>

<pre class="brush:js">
let iterable = new Set([1, 1, 2, 2, 3, 3]);

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

<h3 id="Iterating_over_a_DOM_collection">Iterating over a DOM collection</h3>

<p>Iterating over DOM collections like {{domxref("NodeList")}}: the following example adds a <code>read</code> class to paragraphs that are direct descendants of an article:</p>

<pre class="brush:js">
// Note: This will only work in platforms that have
// implemented NodeList.prototype[Symbol.iterator]
let articleParagraphs = document.querySelectorAll("article &gt; p");

for (let paragraph of articleParagraphs) {
  paragraph.classList.add("read");
}
</pre>

<h3 id="Iterating_over_generators">Iterating over generators</h3>

<p>You can also iterate over <a href="/en-US/docs/Web/JavaScript/Reference/Statements/function*">generators</a>:</p>

<pre class="brush:js">
function* fibonacci() { // a generator function
  let [prev, curr] = [1, 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 &gt;= 1000) {
    break;
  }
}
</pre>

<h3 id="Iterating_over_other_iterable_objects">Iterating over other iterable objects</h3>

<p>You can also iterate over an object that explicitly implements <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols#iterable">iterable</a> protocol:</p>

<pre class="brush:js">
var iterable = {
  [Symbol.iterator]() {
    return {
      i: 0,
      next() {
        if (this.i &lt; 3) {
          return { value: this.i++, done: false };
        }
        return { value: undefined, done: true };
      }
    };
  }
};

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

<h3 id="Difference_between_for...of_and_for...in">Difference between <code>for...of</code> and <code>for...in</code></h3>

<p>The <code><a href="/en-US/docs/Web/JavaScript/Reference/Statements/for...in" title="en-US/docs/JavaScript/Reference/Statements/for...in">for...in</a></code> loop will iterate over all enumerable properties of an object.</p>

<p>The <code>for...of</code> syntax is specific to <strong>collections</strong>, rather than all objects. It will iterate in this manner over the elements of any collection that has a <code>[Symbol.iterator]</code> property.</p>

<p>The following example shows the difference between a <code>for...of</code> loop and a <code>for...in</code> loop.</p>

<pre class="brush:js">
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 of iterable) {
  console.log(i); // logs 3, 5, 7
}
</pre>

<h2 id="Specifications">Specifications</h2>

<table class="standard-table">
 <tbody>
  <tr>
   <th scope="col">Specification</th>
   <th scope="col">Status</th>
   <th scope="col">Comment</th>
  </tr>
  <tr>
   <td>{{SpecName('ES6', '#sec-for-in-and-for-of-statements', 'for...of statement')}}</td>
   <td>{{Spec2('ES6')}}</td>
   <td>Initial definition.</td>
  </tr>
  <tr>
   <td>{{SpecName('ESDraft', '#sec-for-in-and-for-of-statements', 'for...of statement')}}</td>
   <td>{{Spec2('ESDraft')}}</td>
   <td>&nbsp;</td>
  </tr>
 </tbody>
</table>

<h2 id="Browser_compatibility">Browser compatibility</h2>

<p>{{CompatibilityTable}}</p>

<div id="compat-desktop">
<table class="compat-table">
 <tbody>
  <tr>
   <th>Feature</th>
   <th>Chrome</th>
   <th>Firefox (Gecko)</th>
   <th>Edge</th>
   <th>Opera</th>
   <th>Safari</th>
  </tr>
  <tr>
   <td>Basic support</td>
   <td>{{CompatChrome(38)}} <a href="#Chrome_note_1">[1]</a><br />
    {{CompatChrome(51)}} <a href="#Chrome_note_3">[3]</a></td>
   <td>{{CompatGeckoDesktop("13")}} <a href="#Gecko_note_2">[2]</a></td>
   <td>12</td>
   <td>25</td>
   <td>7.1</td>
  </tr>
 </tbody>
</table>
</div>

<div id="compat-mobile">
<table class="compat-table">
 <tbody>
  <tr>
   <th>Feature</th>
   <th>Android</th>
   <th>Chrome for Android</th>
   <th>Firefox Mobile (Gecko)</th>
   <th>IE Mobile</th>
   <th>Opera Mobile</th>
   <th>Safari Mobile</th>
  </tr>
  <tr>
   <td>Basic support</td>
   <td>5.1</td>
   <td>{{CompatChrome(38)}} [1]</td>
   <td>{{CompatGeckoMobile("13")}} [2]</td>
   <td>{{CompatNo}}</td>
   <td>{{CompatUnknown}}</td>
   <td>8</td>
  </tr>
 </tbody>
</table>
</div>

<p><a name="Chrome_note_1">[1]</a> From Chrome 29 to Chrome 37 this feature was available behind a preference. In chrome://flags/#enable-javascript-harmony, activate the entry “Enable Experimental JavaScript”.</p>

<p><a name="Gecko_note_2">[2]</a> From Gecko 17 (Firefox 17 / Thunderbird 17 / SeaMonkey 2.14) to Gecko 26 (Firefox 26 / Thunderbird 26 / SeaMonkey 2.23 / Firefox OS 1.2) the <code>iterator</code> property was used (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=907077">bug 907077</a>), and from Gecko 27 to Gecko 35 the <code>"@@iterator"</code> placeholder was used. In Gecko 36 (Firefox 36 / Thunderbird 36 / SeaMonkey 2.33), the <code>@@iterator</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol">symbol</a> got implemented (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=918828">bug 918828</a>).</p>

<p><a name="Chrome_note_3">[3]</a> Support for iteration of objects was added in Chrome 51.</p>

<h2 id="See_also">See also</h2>

<ul>
 <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for_each...in">for each...in</a> - a similar statement, but iterates over the values of object's properties, rather than the property names themselves (deprecated).</li>
 <li>{{jsxref("Array.prototype.forEach()")}}</li>
 <li><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/forEach">Map.prototype.forEach()</a></li>
</ul>
Revert to this revision