HTML: Markup language
CSS: Styling language
JavaScript: Scripting language
Web APIs: Programming interfaces
All web technology
Learn web development
Discover our tools
Get to know MDN better
Esta página ha sido traducida del inglés por la comunidad. Aprende más y únete a la comunidad de MDN Web Docs.
View in English Always switch to English
This feature is well established and works across many devices and browser versions. It’s been available across browsers since julio de 2015.
La sentencia for...of ejecuta un bucle que opera sobre una secuencia de valores provenientes de un objeto iterable. Los objetos iterables incluyen instancias de objetos nativos como Array, String, TypedArray, Map, Set, NodeList (y otras colecciones del DOM), así como el objeto arguments, generadores producidos por funciones generadoras, e iterables definidos por el usuario.
for...of
Array
String
TypedArray
Map
Set
NodeList
arguments
const array1 = ["a", "b", "c"]; for (const element of array1) { console.log(element); } // Expected output: "a" // Expected output: "b" // Expected output: "c"
for (variable of iterable) statement
variable
Recibe un valor de la secuencia en cada iteración. Puede ser una declaración con const, let, o var, o un objetivo de asignación (p. ej., una variable previamente declarada, una propiedad de objeto o un patrón de asignación por desestructuración). Las variables declaradas con var no son locales al bucle, es decir, están en el mismo ámbito en el que se encuentra el bucle for...of.
const
let
var
iterable
Un objeto iterable. La fuente de la secuencia de valores sobre la que opera el bucle.
statement
Una sentencia que se ejecutará en cada iteración. Puede hacer referencia a variable. Puedes usar una sentencia de bloque para ejecutar múltiples sentencias.
Un bucle for...of opera sobre los valores provenientes de un iterable, uno por uno y en orden secuencial. Cada operación del bucle sobre un valor se denomina iteración, y se dice que el bucle itera sobre el iterable. Cada iteración ejecuta sentencias que pueden referirse al valor actual de la secuencia.
Cuando un bucle for...of itera sobre un iterable, primero llama al método [Symbol.iterator]() del iterable, que devuelve un iterador, y luego llama repetidamente al método next() del iterador resultante para producir la secuencia de valores que se asignarán a variable.
[Symbol.iterator]()
next()
Un bucle for...of finaliza cuando el iterador se ha completado (el resultado de next() es un objeto con done: true). Al igual que otras sentencias de bucle, puedes usar sentencias de control de flujo dentro de statement:
done: true
break
continue
Si el bucle for...of termina prematuramente (p. ej., se encuentra una sentencia break o se produce un error), se llama al método return() del iterador para realizar cualquier limpieza.
return()
La parte variable de for...of acepta cualquier cosa que pueda preceder al operador =. Puedes usar const para declarar la variable siempre y cuando no se reasigne dentro del cuerpo del bucle (puede cambiar entre iteraciones, porque son dos variables separadas). De lo contrario, puedes usar let.
=
const iterable = [10, 20, 30]; for (let value of iterable) { value += 1; console.log(value); } // 11 // 21 // 31
Nota: Cada iteración crea una nueva variable. Reasignar la variable dentro del cuerpo del bucle no afecta al valor original en el iterable (un arreglo, en este caso).
Puedes usar desestructuración para asignar múltiples variables locales, o usar un acceso a propiedades como for (x.y of iterable) para asignar el valor a una propiedad de objeto.
for (x.y of iterable)
Sin embargo, una regla especial prohíbe usar async como el nombre de la variable. Esta es una sintaxis inválida:
async
let async; for (async of [1, 2, 3]); // SyntaxError: The left-hand side of a for-of loop may not be 'async'.
Esto es para evitar la ambigüedad sintáctica con el código válido for (async of => {};;), que es un bucle for.
for (async of => {};;)
for
const iterable = [10, 20, 30]; for (const value of iterable) { console.log(value); } // 10 // 20 // 30
Las cadenas de texto son iteradas por puntos de código Unicode.
const iterable = "boo"; for (const value of iterable) { console.log(value); } // "b" // "o" // "o"
const iterable = new Uint8Array([0x00, 0xff]); for (const value of iterable) { console.log(value); } // 0 // 255
const iterable = new Map([ ["a", 1], ["b", 2], ["c", 3], ]); for (const entry of iterable) { console.log(entry); } // ['a', 1] // ['b', 2] // ['c', 3] for (const [key, value] of iterable) { console.log(value); } // 1 // 2 // 3
const iterable = new Set([1, 1, 2, 2, 3, 3]); for (const value of iterable) { console.log(value); } // 1 // 2 // 3
Puedes iterar sobre el objeto arguments para examinar todos los parámetros pasados a una función.
function foo() { for (const value of arguments) { console.log(value); } } foo(1, 2, 3); // 1 // 2 // 3
El siguiente ejemplo añade una clase read a los párrafos que son descendientes directos del elemento <article> iterando sobre una colección NodeList del DOM.
read
<article>
const articleParagraphs = document.querySelectorAll("article > p"); for (const paragraph of articleParagraphs) { paragraph.classList.add("read"); }
Iterando sobre un objeto con un método [Symbol.iterator]() que devuelve un iterador personalizado:
const iterable = { [Symbol.iterator]() { let i = 1; return { next() { if (i <= 3) { return { value: i++, done: false }; } return { value: undefined, done: true }; }, }; }, }; for (const value of iterable) { console.log(value); } // 1 // 2 // 3
Iterando sobre un objeto con un método generador [Symbol.iterator]():
const iterable = { *[Symbol.iterator]() { yield 1; yield 2; yield 3; }, }; for (const value of iterable) { console.log(value); } // 1 // 2 // 3
Los iteradores iterables (iteradores con un método [Symbol.iterator]() que devuelve this) son una técnica bastante común para hacer que los iteradores sean utilizables en sintaxis que esperan iterables, como for...of.
this
let i = 1; const iterator = { next() { if (i <= 3) { return { value: i++, done: false }; } return { value: undefined, done: true }; }, [Symbol.iterator]() { return this; }, }; for (const value of iterator) { console.log(value); } // 1 // 2 // 3
function* source() { yield 1; yield 2; yield 3; } const generator = source(); for (const value of generator) { console.log(value); } // 1 // 2 // 3
La ejecución de la sentencia break en el primer bucle hace que termine prematuramente. El iterador aún no ha terminado, por lo que el segundo bucle continuará desde donde se detuvo el primero.
const source = [1, 2, 3]; const iterator = source[Symbol.iterator](); for (const value of iterator) { console.log(value); if (value === 1) { break; } console.log("Esta cadena no será registrada."); } // 1 // Otro bucle usando el mismo iterador // continúa donde lo dejó el último bucle. for (const value of iterator) { console.log(value); } // 2 // 3 // El iterador está agotado. // Este bucle no ejecutará ninguna iteración. for (const value of iterator) { console.log(value); } // [Sin salida]
Los generadores implementan el método return(), lo que hace que la función generadora regrese anticipadamente cuando el bucle termina. Esto hace que los generadores no sean reutilizables entre bucles.
function* source() { yield 1; yield 2; yield 3; } const generator = source(); for (const value of generator) { console.log(value); if (value === 1) { break; } console.log("Esta cadena no será registrada."); } // 1 // El generador está agotado. // Este bucle no ejecutará ninguna iteración. for (const value of generator) { console.log(value); } // [Sin salida]
Ambas sentencias for...in y for...of iteran sobre algo. La principal diferencia entre ellas radica en sobre qué iteran.
for...in
La sentencia for...in itera sobre las propiedades de cadena enumerables de un objeto, mientras que la sentencia for...of itera sobre los valores que el objeto iterable define para ser iterados.
El siguiente ejemplo muestra la diferencia entre un bucle for...of y un bucle for...in cuando se utilizan con un Array.
Object.prototype.objCustom = function () {}; Array.prototype.arrCustom = function () {}; const iterable = [3, 5, 7]; iterable.foo = "hello"; for (const i in iterable) { console.log(i); } // "0", "1", "2", "foo", "arrCustom", "objCustom" for (const i in iterable) { if (Object.hasOwn(iterable, i)) { console.log(i); } } // "0" "1" "2" "foo" for (const i of iterable) { console.log(i); } // 3 5 7
El objeto iterable hereda las propiedades objCustom y arrCustom porque contiene tanto Object.prototype como Array.prototype en su cadena de prototipos.
objCustom
arrCustom
Object.prototype
Array.prototype
El bucle for...in solo registra las propiedades enumerables del objeto iterable. No registra los elementos del array 3, 5, 7 o "hello" porque no son propiedades, sino valores. Registra los índices del array, así como arrCustom y objCustom, que son propiedades reales. Si no estás seguro de por qué se itera sobre estas propiedades, hay una explicación más detallada de cómo funciona la iteración de arrays y for...in.
3
5
7
"hello"
El segundo bucle es similar al primero, pero utiliza Object.hasOwn() para comprobar si la propiedad enumerable encontrada es propia del objeto, es decir, no heredada. Si lo es, se registra la propiedad. Las propiedades 0, 1, 2 y foo se registran porque son propiedades propias. Las propiedades arrCustom y objCustom no se registran porque son heredadas.
Object.hasOwn()
0
1
2
foo
El bucle for...of itera y registra los valores que son iterable, como un arreglo (que es iterable), define para ser iterados. Se muestran los elementos del objeto 3, 5, 7, pero ninguna de las propiedades del objeto.
Enable JavaScript to view this browser compatibility table.
Array.prototype.forEach()
Map.prototype.forEach()
Object.entries()