Esta página ha sido traducida del inglés por la comunidad.Aprende más y únete a la comunidad de MDN Web Docs.
for...of
Baseline Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since julio de 2015.
La sentenciafor...of ejecuta un bucle que opera sobre una secuencia de valores provenientes de unobjeto iterable. Los objetos iterables incluyen instancias de objetos nativos comoArray,String,TypedArray,Map,Set,NodeList (y otras colecciones del DOM), así como el objetoarguments,generadores producidos porfunciones generadoras, e iterables definidos por el usuario.
In this article
Pruébalo
const array1 = ["a", "b", "c"];for (const element of array1) { console.log(element);}// Expected output: "a"// Expected output: "b"// Expected output: "c"Sintaxis
for (variable of iterable) statementvariableRecibe un valor de la secuencia en cada iteración. Puede ser una declaración con
const,let, ovar, o un objetivo deasignación (p. ej., una variable previamente declarada, una propiedad de objeto o unpatrón de asignación por desestructuración). Las variables declaradas convarno son locales al bucle, es decir, están en el mismo ámbito en el que se encuentra el buclefor...of.iterableUn objeto iterable. La fuente de la secuencia de valores sobre la que opera el bucle.
statementUna sentencia que se ejecutará en cada iteración. Puede hacer referencia a
variable. Puedes usar unasentencia de bloque para ejecutar múltiples sentencias.
Descripción
Un buclefor...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 denominaiteración, y se dice que el bucleitera sobre el iterable. Cada iteración ejecuta sentencias que pueden referirse al valor actual de la secuencia.
Cuando un buclefor...of itera sobre un iterable, primero llama al método[Symbol.iterator]() del iterable, que devuelve uniterador, y luego llama repetidamente al métodonext() del iterador resultante para producir la secuencia de valores que se asignarán avariable.
Un buclefor...of finaliza cuando el iterador se ha completado (el resultado denext() es un objeto condone: true). Al igual que otras sentencias de bucle, puedes usarsentencias de control de flujo dentro destatement:
breakdetiene la ejecución destatementy va a la primera sentencia después del bucle.continuedetiene la ejecución destatementy va a la siguiente iteración del bucle.
Si el buclefor...of termina prematuramente (p. ej., se encuentra una sentenciabreak o se produce un error), se llama al métodoreturn() del iterador para realizar cualquier limpieza.
La partevariable defor...of acepta cualquier cosa que pueda preceder al operador=. Puedes usarconst 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 usarlet.
const iterable = [10, 20, 30];for (let value of iterable) { value += 1; console.log(value);}// 11// 21// 31Nota: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 usardesestructuración para asignar múltiples variables locales, o usar un acceso a propiedades comofor (x.y of iterable) para asignar el valor a una propiedad de objeto.
Sin embargo, una regla especial prohíbe usarasync como el nombre de la variable. Esta es una sintaxis inválida:
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álidofor (async of => {};;), que es un buclefor.
Ejemplos
>Iterando sobre un Array
const iterable = [10, 20, 30];for (const value of iterable) { console.log(value);}// 10// 20// 30Iterando sobre una cadena de texto
Las cadenas de texto soniteradas por puntos de código Unicode.
const iterable = "boo";for (const value of iterable) { console.log(value);}// "b"// "o"// "o"Iterando sobre un TypedArray
const iterable = new Uint8Array([0x00, 0xff]);for (const value of iterable) { console.log(value);}// 0// 255Iterando sobre un Map
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// 3Iterando sobre un Set
const iterable = new Set([1, 1, 2, 2, 3, 3]);for (const value of iterable) { console.log(value);}// 1// 2// 3Iterando sobre el objeto arguments
Puedes iterar sobre el objetoarguments 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// 3Iterando sobre un NodeList
El siguiente ejemplo añade una claseread a los párrafos que son descendientes directos del elemento<article> iterando sobre una colecciónNodeList del DOM.
const articleParagraphs = document.querySelectorAll("article > p");for (const paragraph of articleParagraphs) { paragraph.classList.add("read");}Iterando sobre un iterable definido por el usuario
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// 3Iterando 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// 3Lositeradores iterables (iteradores con un método[Symbol.iterator]() que devuelvethis) son una técnica bastante común para hacer que los iteradores sean utilizables en sintaxis que esperan iterables, comofor...of.
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// 3Iterando sobre un generador
function* source() { yield 1; yield 2; yield 3;}const generator = source();for (const value of generator) { console.log(value);}// 1// 2// 3Salida anticipada
La ejecución de la sentenciabreak 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étodoreturn(), 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]Diferencia entre for...of y for...in
Ambas sentenciasfor...in yfor...of iteran sobre algo. La principal diferencia entre ellas radica en sobre qué iteran.
La sentenciafor...in itera sobre laspropiedades de cadena enumerables de un objeto, mientras que la sentenciafor...of itera sobre los valores que elobjeto iterable define para ser iterados.
El siguiente ejemplo muestra la diferencia entre un buclefor...of y un buclefor...in cuando se utilizan con unArray.
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 7El objetoiterable hereda las propiedadesobjCustom yarrCustom porque contiene tantoObject.prototype comoArray.prototype en sucadena de prototipos.
El buclefor...in solo registra laspropiedades enumerables del objetoiterable. No registra loselementos del array3,5,7 o"hello" porque no sonpropiedades, sinovalores. Registra losíndices del array, así comoarrCustom yobjCustom, 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 laiteración de arrays yfor...in.
El segundo bucle es similar al primero, pero utilizaObject.hasOwn() para comprobar si la propiedad enumerable encontrada es propia del objeto, es decir, no heredada. Si lo es, se registra la propiedad. Las propiedades0,1,2 yfoo se registran porque son propiedades propias. Las propiedadesarrCustom yobjCustom no se registran porque son heredadas.
El buclefor...of itera y registra losvalores que soniterable, como un arreglo (que esiterable), define para ser iterados. Se muestran loselementos del objeto3,5,7, pero ninguna de laspropiedades del objeto.
Especificaciones
| Specification |
|---|
| ECMAScript® 2026 Language Specification> # sec-for-in-and-for-of-statements> |