Pregunta 1Si un bucle while empieza con su condición cumplida y el cuerpo nunca cambia la variable que comprueba la condición, ¿qué pasa?
Repetir según una condición — while, do...while, break y continue
Aprende while y do...while en JavaScript: repetir cuando no sabes cuántas veces, evitar bucles infinitos y cuándo usar continue o break.
Dar un lugar a quien está en la lista de espera cada vez que se libera una reserva, o seguir comprando mientras el saldo alcance: en tareas así sabes cuándo parar, pero no puedes saber de antemano cuántas veces vas a repetir.
En este artículo verás while y do...while, que repiten según una condición; continue, que se salta una vuelta, y break, que sale del bucle.
Repetir sin un número fijo de vueltas — while y la actualización de la condición
Supón que se liberan algunos lugares y quieres dárselos en orden a quienes encabezan la lista de espera. Cada persona que pasa ocupa un lugar, y paras en cuanto quedan 0 lugares. Lo que detiene el bucle es un estado ("mientras queden lugares libres"), no un número de vueltas, así que un bucle for que cuenta no lo expresa de forma natural.
Un bucle while (una sentencia que repite el cuerpo entre llaves mientras se cumple la condición entre paréntesis) solo lleva una condición entre paréntesis. La condición se comprueba en cada vuelta, antes de entrar al cuerpo.
El valor inicial lo escribes tú antes del bucle, y la actualización de la variable que comprueba la condición también la escribes tú, dentro del cuerpo.
const waitingList = ["Ana", "Carlos", "Lucía"]; // lista de espera
let openSeats = 2; // lugares libres
// Da un lugar solo mientras queden lugares libres
while (openSeats > 0) {
const name = waitingList.shift();
openSeats--; // equivale a openSeats = openSeats - 1
console.log(`${name} obtiene un lugar (lugares libres: ${openSeats})`);
}
// Ana obtiene un lugar (lugares libres: 1)
// Carlos obtiene un lugar (lugares libres: 0)
console.log(`Siguen en espera: ${waitingList.length}`); // Siguen en espera: 1
En un bucle for, la expresión de actualización tiene un lugar fijo dentro de los paréntesis, pero con while decides tú en qué parte del cuerpo ponerla. La contrapartida de esa libertad es que nada te impide olvidarla: el código sigue siendo perfectamente válido sin la actualización.
Si olvidas la actualización, el bucle nunca se detiene
Si la condición nunca deja de cumplirse, el cuerpo se repite para siempre. Si te olvidas de escribir openSeats--, los lugares libres se quedan en 2, así que la comprobación siempre da el mismo resultado. La consola muestra un aviso de tiempo agotado a los 15 segundos, pero el bucle no se detiene, y los demás ejercicios tampoco funcionarán hasta que recargues la página. Cambia siempre en algún punto del cuerpo la variable que comprueba la condición.
Ejecutar una vez primero — el orden de comprobación en do...while
Cuando falla el envío de una notificación, la reintentas varias veces hasta que salga bien. Tienes que enviarla al menos una vez para tener un resultado que comprobar, pero while comprueba su condición antes de entrar al cuerpo, así que, según el valor inicial de la variable de la condición, el bucle puede terminar sin enviar nada.
Un bucle do...while (una sentencia que ejecuta el cuerpo una vez y después comprueba la condición) se escribe do { cuerpo } while (condición);, y todo, hasta el punto y coma final, forma una sola sentencia. Como la comprobación va después del cuerpo, el cuerpo se ejecuta una vez aunque la condición no se cumpla desde el principio.
const attempts = [false, false, true]; // resultados de envío preparados de antemano (true = éxito)
let sent = true; // quedó en true por la notificación anterior
let tried = 0;
// while comprueba primero, así que termina sin enviar ni una vez
while (!sent && tried < attempts.length) {
sent = attempts[tried];
tried++;
}
console.log(`Envíos con while: ${tried}`); // Envíos con while: 0
// do...while hace el primer envío antes de comprobar y usa el resultado para decidir si sigue
do {
sent = attempts[tried];
tried++;
console.log(`Intento ${tried}: ${sent ? "correcto" : "fallido"}`);
} while (!sent && tried < attempts.length);
// Intento 1: fallido / Intento 2: fallido / Intento 3: correcto
sent todavía en true. while termina con solo la comprobación, mientras que do...while envía una vez y después decide si sigue.Solo la primera vuelta se salta la comprobación; a partir de ahí, el bucle se repite solo mientras se cumple la condición, igual que while. Si no quieres que el cuerpo se ejecute ni una vez cuando la condición no se cumple, elige while. Si quieres que se ejecute una vez antes de mirar el resultado, elige do...while.
Saltarse solo una vuelta — cuándo usar continue
Cuando recorres una lista de envíos de arriba abajo, querrás saltarte las líneas sin existencias y pasar a la siguiente. Cuantas más condiciones para saltar añades, más se anidan las llaves de los if, y el código de envío, que es lo que de verdad te interesa, acaba enterrado dentro de ellas.
Con continue (una sentencia que se salta el resto de la vuelta actual y pasa a la siguiente), puedes cortar una vuelta en cuanto se da una condición que quieres saltar. El bucle en sí sigue, así que la siguiente vuelta empieza con normalidad por la comprobación de la condición.
const names = ["Agenda A5", "Lámpara de escritorio", "Hub USB"];
const stocks = [12, 0, 5]; // 0 significa sin existencias
let index = 0;
while (index < names.length) {
const name = names[index];
const stock = stocks[index];
index++; // se avanza primero para que continue no se lo salte
// En las líneas sin existencias, sáltate el resto de esta vuelta y pasa a la siguiente
if (stock === 0) {
console.log(`${name}: sin existencias, se omite`);
continue;
}
console.log(`${name}: se envían ${stock}`);
}
// Agenda A5: se envían 12
// Lámpara de escritorio: sin existencias, se omite
// Hub USB: se envían 5
| Línea procesada | stock y comprobación | Resultado de esa vuelta |
|---|---|---|
| Línea 1: Agenda A5 | stock es 12, no 0 | Imprime "se envían 12" |
| Línea 2: Lámpara de escritorio | stock es 0, así que continue | No se ejecuta el envío |
| Línea 3: Hub USB | stock es 5, no 0 | Imprime "se envían 5" |
continue solo se salta las líneas que hay entre él y el final del cuerpo. También puedes usar continue en el cuerpo de for y for...of, y como la expresión de actualización de los paréntesis de un for está fuera del cuerpo, también se ejecuta en las vueltas que llegan a continue.
continue también se salta tu línea de actualización
Si pones index++ después de continue, index no avanza en la vuelta que se salta. La siguiente vuelta vuelve a leer la misma línea, stock sigue en 0, la condición no cambia y el bucle nunca termina. Actualiza la variable que comprueba la condición antes de continue.
Parar en cuanto lo encuentras — adónde te lleva break
Supón que quieres revisar un registro (log) desde arriba y encontrar solo el primer error. Si sigues leyendo hasta el final después de encontrarlo, es trabajo desperdiciado y, según cómo lo escribas, un error posterior puede sobrescribir firstError.
Con break (una sentencia que termina de inmediato el bucle en el que está), puedes salir del bucle en la vuelta en que se cumple la condición. Es la misma sentencia que usaste para salir de un switch en el artículo sobre condicionales. El valor que encuentres lo vas a usar fuera del bucle, así que declara firstError antes del bucle.
const logs = ["INFO Inicio", "WARN Respuesta lenta", "ERROR Pago fallido", "ERROR Reenvío fallido"];
let index = 0;
let firstError = "";
while (index < logs.length) {
const line = logs[index];
index++;
if (line.startsWith("ERROR")) {
firstError = line;
break; // ya se encontró el primero, así que no se revisa el resto
}
}
console.log(`Primer error: ${firstError}`); // Primer error: ERROR Pago fallido
console.log(`Líneas revisadas: ${index}`); // Líneas revisadas: 3
const line = logs[index]— la línea que se revisa en esta vuelta- Después de
break, la ejecución sale de las llaves y pasa a la siguiente línea conconsole.log
firstError = line— guarda la línea encontradabreak— sale del while externo, no de estas llaves- Las líneas que haya debajo de
breaknunca se ejecutan
break ni las vueltas restantes. La ejecución sigue en la línea que viene después de la llave de cierre del while.Incluso en la vuelta que llega a break, el index++ escrito antes ya se ejecutó. Por eso index se queda en 3, y el "Líneas revisadas: 3" que se imprime después del bucle coincide con la posición de la línea encontrada, contando desde 1.
Verificación de conocimientos
Responde cada pregunta una a una.
Pregunta 2Si la condición no se cumple desde el principio, ¿cuántas veces se ejecuta el cuerpo de un do...while?
Pregunta 3¿Qué pasa a continuación cuando se ejecuta continue dentro de un bucle?