for...of

La sentencia sentencia for...of ejecuta un bloque de c贸digo para cada elemento de un objeto iterable, como lo son: String, Array, objetos similares a array (por ejemplo, arguments or NodeList), TypedArray, Map, Set e iterables definidos por el usuario.

Sintaxis

for (variable of iterable) {
  statement
}
variable
En cada iteraci贸n el elemento (propiedad enumerable) correspondiente es asignado a variable
iterable
Objeto cuyas propiedades enumerables son iteradas. 

Ejemplos

Iterando un Array

let iterable = [10, 20, 30];

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

Es posible usar const en lugar de let si no se va a modificar la variable dentro del bloque.

let iterable = [10, 20, 30];

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

Iterando un String

let iterable = "boo";

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

Iterando un TypedArray

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

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

Iterando un 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

Iterando un Set

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

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

Iterando un objeto arguments

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

// 1
// 2
// 3

Iterando una colecci贸n del DOM

Iterando colecciones del DOM como un NodeList: el siguiente ejemplo a帽ade la clase "read" a los p谩rrafos (<p>) que son descendientes directos de un (<article>):

// Nota: Esto solo funcionar谩 en plataformas que tengan
// implementado NodeList.prototype[Symbol.iterator]
let articleParagraphs = document.querySelectorAll("article > p");

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

Clausurando iteraciones

En los bucles for...of, se puede causar que la iteraci贸n termine de un modo brusco usando: breakcontinue[4]throw or return[5]. En estos casos la iteraci贸n se cierra.

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

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

Iterando generadores

Tambi茅n es posible iterar las nuevas funciones generator:

function* fibonacci() { // una funci贸n generador
  let [prev, curr] = [0, 1];
  while (true) {
    [prev, curr] = [curr, prev + curr];
    yield curr;
  }
}

for (let n of fibonacci()) {
  console.log(n);
  // interrumpir la secuencia en 1000
  if (n >= 1000) {
    break;
  }
}

No se deben reutilizar los generadores

Los generadores no deben ser reutilizados, incluso si el bucle for...of se ha terminado antes de tiempo con la sentencia break. Una vez abandonado el bucle, el generador est谩 cerrado y tratar de iterar sobre 茅l de nuevo no dar谩 m谩s resultados. Firefox no ha implementado a煤n este comportamiento y el generador puede ser reutilizado en contra de lo escrito en el est谩ndar ES6 (13.7.5.13, step 5m), pero esto cambiar谩 una vez que el bug error 1147371 haya sido corregido.

var gen = (function *(){
  yield 1;
  yield 2;
  yield 3;
})();
for (let o of gen) {
  console.log(o);
  break;  // Finaliza la iteraci贸n
}

// El generador no debe ser reutilizado, lo siguiente no tiene sentido
for (let o of gen) {
  console.log(o); // Nunca ser谩 llamado
}

Iterando otros objetos iterables

Es posible, adem谩s, iterar un objeto que explicitamente implemente el protocolo 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

Diferencia entre for...of y for...in

El bucle for...in iterar谩 sobre todas las propiedades de un objeto. M谩s tecnicamente, iterar谩 sobre cualquier propiedad en el objeto que haya sido internamente definida con su propiedad [[Enumerable]] configurada como true

La sintaxis de  for...of es espec铆fica para las colecciones, y no para todos los objetos. Esta Iterar谩 sobre cualquiera de los elementos de una colecci贸n que tengan la propiedad [Symbol.iterator].

El siguiente ejemplo muestra las diferencias entre un bucle for...of y un bucle for...in

let arr = [3, 5, 7];
arr.foo = "hola";

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

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

Especificaciones

Especificaci贸n Estado Cometario
ECMAScript 2015 (6th Edition, ECMA-262)
La definici贸n de 'for...of statement' en esta especificaci贸n.
Standard Definici贸n inicial.
ECMAScript (ECMA-262)
La definici贸n de 'for...of statement' en esta especificaci贸n.
Living Standard

Compatibilidad de navegadores

We're converting our compatibility data into a machine-readable JSON format. This compatibility table still uses the old format, because we haven't yet converted the data it contains. Find out how you can help! (en-US)

Caracter铆stica Chrome Firefox (Gecko) Edge Opera Safari
Soporte b谩sico 38 [1]
51 [3]
13 (13) [2] [4] 12 25 7.1
Caracter铆stica Android Chrome for Android Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile
Soporte b谩sico 5.1 38 [1] 13.0 (13) [2] Sin soporte ? 8

[1] Desde Chrome 29 a Chrome 37 esta funcionalidad estuvo disponible al activar la opci贸n chrome://flags/#enable-javascript-harmony: 鈥淛avaScript experimental鈥.

[2] Antes de Firefox 51, el uso de for...of usando const resultaba en un SyntaxError ("missing = in const declaration"). El problema ha sido resuelto (error 1101653).

[3] Chrome 51 a帽adi贸 soporte para iterar objetos.

[4] Firefox a煤n permite el uso de un generador despu茅s de haber interrumpido el bucle error 1147371. Como se vio m谩s arriba, no se deben reutilizar los generadores.

Vea tambi茅n