El bucle for en JavaScript
Cuando sabes de antemano cuántas veces quieres repetir algo, el for es la herramienta que necesitas. En una sola línea de cabecera junta las tres piezas de un bucle contado: el valor inicial, la condición de parada y el paso.
Cinco iteraciones, cinco líneas en la salida. Vamos por partes analizando la cabecera:
let i = 0se ejecuta una sola vez, antes de que arranque el bucle. Inicializa el contador.i < 5se evalúa antes de cada iteración. Si datrue, se ejecuta el cuerpo; si dafalse, el bucle termina.i++se ejecuta después de cada iteración, justo antes de volver a comprobar la condición.
Las tres partes van separadas por punto y coma, no por comas. Las tres son opcionales, pero omitirlas no es lo habitual: en ese caso normalmente tirarías de while.
Cómo encajan las piezas del bucle for en javascript
Para fijar bien el orden, lo mejor es trazar una iteración a mano:
Paso a paso:
let i = 1— se crea el contador y se inicializa en 1.- Se comprueba
i <= 3— estrue, así que se ejecuta el cuerpo. Imprime1. - Se ejecuta
i++— ahoraivale 2. - Se comprueba
i <= 3—true. Imprime2. - Se ejecuta
i++— ahoraivale 3. - Se comprueba
i <= 3—true. Imprime3. - Se ejecuta
i++— ahoraivale 4. - Se comprueba
i <= 3—false. Sale del bucle.
Ojo con esto: el paso de actualización se ejecuta después del cuerpo, no antes. Ahí es donde mucha gente se lía.
Recorrer un array en JavaScript con for
La tarea más típica de un bucle for es recorrer un array. El contador hace doble función y sirve también como índice:
Un par de detalles que conviene tener en cuenta:
- Los arrays empiezan en cero. El primer elemento está en el índice
0y el último enlength - 1. - La condición es
i < fruits.length, noi <= fruits.length. Si usas<=, el bucle se pasa una posición y termina imprimiendoundefined. ise declara conlet, así que solo vive dentro del bucle. Fuera de él no existe.
Si solo te interesan los valores y no el índice, for...of es más corto y se lee mejor. Lo vemos en su propio apartado.
break: salir antes de tiempo
break corta el bucle al instante. Va muy bien cuando ya encontraste lo que buscabas y no tiene sentido seguir iterando:
Cuando se ejecuta break, el control salta fuera de la llave de cierre del bucle. No se ejecuta el paso de actualización ni se vuelve a comprobar la condición: el bucle simplemente termina ahí.
continue: saltar la iteración actual
continue se salta el resto de la iteración actual y pasa directo al paso de actualización. El bucle sigue corriendo; lo único que no hace es terminar la pasada actual.
Los números pares caen en el continue y se saltan el console.log. Así que solo se imprimen los impares. El continue viene muy bien cuando quieres descartar ciertas iteraciones sin tener que meter todo el resto del cuerpo dentro de un if.
Incrementos distintos de +1
El paso de actualización es simplemente una expresión. No tiene por qué ser i++. Por ejemplo, para contar de dos en dos:
Cuenta regresiva:
Recorre un array al revés (un bucle for inverso en JavaScript es bastante útil cuando vas eliminando elementos sobre la marcha):
Elijas lo que elijas, la regla es la misma: la condición y la actualización tienen que ir coordinadas para que, en algún momento, la condición termine siendo false. Si no lo hacen, el bucle no para nunca. for (let i = 0; i < 10; i--) es un bucle infinito en JavaScript: i avanza en la dirección equivocada.
Bucle for anidado en JavaScript
Puedes meter un for dentro de otro. El bucle interno se ejecuta por completo en cada iteración del bucle externo.
Nueve líneas de salida: tres iteraciones externas, cada una con tres internas. Dale a cada contador un nombre con significado (row/col, i/j) en vez de reutilizar la misma variable.
Ojo con un detalle: break y continue solo afectan al bucle más interno. Salir con break de un bucle interno no detiene el externo. Si necesitas ese comportamiento, usa una bandera y compruébala en el bucle externo, o extrae el trabajo anidado a una función y usa return para salir.
Errores típicos
Hay varias cosas que suelen pillar a quien empieza:
Errores de uno en uno (off-by-one). i <= arr.length itera una posición de más; i < arr.length - 1 se queda una corta. La forma estándar es i < arr.length.
Olvidar la actualización. Si omites i++ (o su equivalente), el contador nunca cambia y tienes un bucle infinito en JavaScript:
for (let i = 0; i < 10; ) {
console.log(i); // never ends
}
Usar var para el contador. var tiene ámbito de función, así que el contador se escapa del bucle y puede darte sorpresas desagradables con los closures. Quédate con let.
Modificar el array mientras lo recorres. Al eliminar elementos, los índices se desplazan y terminas saltándote posiciones. Si necesitas quitar elementos, recorre el array al revés o crea uno nuevo con filter.
Cuándo usar otra cosa en lugar del for
El bucle for clásico siempre está ahí, pero JavaScript tiene alternativas más cortas para los casos típicos:
- Para recorrer los valores de un array:
for (const item of array)queda más limpio. - Para transformar un array:
array.map(fn)devuelve uno nuevo. - Para filtrar:
array.filter(fn). - Para sumar o acumular:
array.reduce(fn, start). - Para ejecutar algo en cada elemento y ya está:
array.forEach(fn).
Tira del for clásico cuando de verdad necesites el índice, quieras saltarte elementos o cortar a mitad del recorrido, o necesites pasos poco habituales como contar hacia atrás o de dos en dos.
Lo que viene: bucles while
El bucle for brilla cuando sabes de antemano hasta dónde vas a llegar. Cuando no lo sabes —cuando quieres seguir iterando hasta que cambie cierta condición— while y do...while encajan mucho mejor. De eso va la siguiente página.
Preguntas frecuentes
¿Cuál es la sintaxis de un bucle for en JavaScript?
Son tres partes separadas por punto y coma dentro del paréntesis: for (init; condición; actualización) { ... }. La parte init se ejecuta una sola vez al principio, la condición se comprueba antes de cada iteración y la actualización corre al final de cada vuelta. Un ejemplo típico sería for (let i = 0; i < 10; i++) { ... }.
¿Cómo recorro un array en JavaScript?
Con un for clásico y un índice funciona perfecto: for (let i = 0; i < arr.length; i++) { console.log(arr[i]); }. Si no necesitas el índice, for...of queda más limpio: for (const item of arr) { ... }. Y cuando lo que quieres es transformar o filtrar, normalmente lo suyo es tirar de métodos de array como map o filter.
¿Cómo funcionan break y continue dentro de un for?
break sale del bucle de golpe: la ejecución salta directamente al código que hay después del bucle. continue se salta lo que queda de la iteración actual y pasa al paso de actualización, que luego vuelve a comprobar la condición. Los dos afectan solo al bucle más interno, salvo que uses etiquetas (labels).
¿Por qué mi bucle for no termina nunca?
Casi siempre es porque la actualización no acerca la condición a false. Por ejemplo, for (let i = 0; i < 10; i--) se queda en bucle infinito porque i arranca en 0 y va cada vez a más negativo. Revisa que la condición y la actualización vayan en la misma dirección para que la condición acabe siendo falsa en algún momento.