Bucles en JavaScript: for, for...of, for...in y while
Actualizado el 29 de septiembre de 2026
Un bucle repite un bloque de código. JavaScript tiene varios, y elegir el adecuado hace el código más claro: for...of para recorrer los elementos de un array o un texto, el for clásico cuando necesitas controlar el índice, y while cuando no sabes cuántas vueltas vas a dar.
En esta guía vas a ver cada uno, la trampa de for...in con arrays y los errores de índice más comunes.
El for clásico
for (let i = 0; i < 3; i++) {
console.log("vuelta", i);
}
// vuelta 0, vuelta 1, vuelta 2Tiene tres partes separadas por punto y coma: la inicialización (let i = 0), la condición que se revisa antes de cada vuelta (i < 3) y lo que se hace al final de cada vuelta (i++). Sirve cuando necesitas el índice o un recorrido especial, como ir de dos en dos o hacia atrás.
for...of: recorrer los valores
for (const fruta of ["manzana", "pera"]) {
console.log(fruta);
}
for (const letra of "hola") {
console.log(letra); // h, o, l, a
}for...of entrega cada valor directamente, sin índices. Es la forma más clara de recorrer arrays y textos, y la que conviene usar por defecto. La variable puede ser const, porque en cada vuelta se crea una nueva.
for...in: recorrer las claves de un objeto
const auto = { marca: "Toyota", anio: 2020 };
for (const clave in auto) {
console.log(clave, auto[clave]);
}
// marca Toyota
// anio 2020for...in recorre los nombres de las propiedades de un objeto. No lo uses con arrays: entrega los índices como texto ("0", "1") en vez de los valores.
while y do...while
let n = 1234;
let digitos = 0;
while (n > 0) {
n = Math.floor(n / 10); // quita el último dígito
digitos++;
}
// digitos → 4while repite mientras la condición sea verdadera, y la revisa antes de cada vuelta, así que puede no ejecutarse nunca. do { ... } while (condición) la revisa al final: siempre da al menos una vuelta, lo que sirve, por ejemplo, para pedir un dato hasta que sea válido.
break y continue
for (const n of [3, 8, 11, 4]) {
if (n > 10) {
console.log("Encontré", n); // Encontré 11
break; // termina el bucle
}
}
const impares = [];
for (let i = 1; i <= 6; i++) {
if (i % 2 === 0) continue; // salta a la siguiente vuelta
impares.push(i);
}
// impares → [1, 3, 5]Errores comunes
Pasarse del largo con <=
const numeros = [1, 2, 3];
let suma = 0;
for (let i = 0; i <= numeros.length; i++) {
suma += numeros[i];
}
// suma → NaNEl último índice válido es length - 1. Con <=, la última vuelta lee numeros[3], que es undefined, y 6 + undefined es NaN. JavaScript no lanza un error, así que el problema aparece más adelante. Usa < o, mejor, for...of.
for...in con arrays
for (const i in [100, 200]) entrega "0" y "1", como texto. Si haces i + 1 obtienes "01". Para arrays, usa for...of o el for clásico.
Bucle infinito
Si la condición de un while nunca se vuelve falsa, el bucle no termina y el navegador se congela. Revisa que dentro del bucle cambie la variable de la condición. En un for clásico, un error típico es escribir i-- donde iba i++.
Ejercicios resueltos
Intenta resolver cada ejercicio antes de abrir la solución: equivocarse y corregir es la parte que más enseña.
1.Sumar del 1 al n
Escribe una función sumarHasta(n) que devuelva la suma de los enteros del 1 al n, incluido. Si n es 0, devuelve 0.
sumarHasta(5)→15sumarHasta(0)→0sumarHasta(100)→5050
function sumarHasta(n) {
// ...
}Ver soluciónOcultar solución
function sumarHasta(n) {
let total = 0;
for (let i = 1; i <= n; i++) {
total += i;
}
return total;
}Aquí sí corresponde <=, porque el enunciado pide incluir n y no se está indexando un array. total se declara con let porque cambia, y fuera del bucle, para que no se reinicie en cada vuelta. Con n = 0 la condición 1 <= 0 es falsa desde el principio y se devuelve 0.
2.Contar vocales
Escribe una función contarVocales(texto) que cuente las vocales, sin distinguir mayúsculas y contando las que llevan tilde.
contarVocales("Murciélago")→5contarVocales("xyz")→0
function contarVocales(texto) {
// ...
}Ver soluciónOcultar solución
function contarVocales(texto) {
let contador = 0;
for (const letra of texto.toLowerCase()) {
if ("aeiouáéíóú".includes(letra)) {
contador++;
}
}
return contador;
}for...of recorre el texto letra por letra. Pasar todo a minúsculas antes evita listar también las mayúsculas, e includes() pregunta si la letra está en el texto de vocales. Es el patrón del contador: parte en 0 y suma 1 cuando se cumple la condición.
3.FizzBuzz
Escribe una función fizzBuzz(n) que devuelva un array con los números del 1 al n como texto, pero reemplazando los múltiplos de 3 por "Fizz", los de 5 por "Buzz" y los de ambos por "FizzBuzz".
fizzBuzz(15).join(" ");
// → "1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14 FizzBuzz"function fizzBuzz(n) {
// ...
}Ver soluciónOcultar solución
function fizzBuzz(n) {
const resultado = [];
for (let i = 1; i <= n; i++) {
if (i % 15 === 0) resultado.push("FizzBuzz");
else if (i % 3 === 0) resultado.push("Fizz");
else if (i % 5 === 0) resultado.push("Buzz");
else resultado.push(String(i));
}
return resultado;
}Es un ejercicio clásico de entrevistas, y la trampa está en el orden: si se pregunta primero por el 3, el 15 entra en "Fizz" y nunca llega a "FizzBuzz". Por eso el caso de ambos múltiplos (divisible por 15) va primero. String(i) convierte el número a texto, como pide el enunciado.