Funciones flecha (arrow functions) en JavaScript explicadas claramente
Jairo
Un bucle es una estructura que repite un bloque de código mientras se cumpla una condición. Me gusta explicarlo así: si hay una tarea repetitiva con una condición de salida, úsalo. En mi día a día, cuando tengo que procesar listas, validar entradas o calcular resultados paso a paso, tiro de bucles.
Un ejemplo mínimo con while:
let i = 0;
while (i < 3) {
console.log(i);
i++; // actualización
}
Aquí aparecen siempre tres piezas mentales: inicialización, condición y actualización. En mi caso, esa tríada me evita el 90% de errores tontos.
Nota desde la práctica: como me contaste, “los bucles son para tareas repetitivas con base en una condición”. Esa frase es oro, y la usaremos como brújula en todas las secciones.
Los bucles infinitos ocurren cuando la condición nunca se vuelve falsa o la actualización no progresa. Señales típicas: la CPU se dispara, la página se congela y los logs no paran.
Checklist rápido para evitarlos:
Ejemplo antivirus de infinitos con tope duro:
let intentos = 0;
const LIMITE = 1000;
while (condicionSigueSiendoVerdadera()) {
// ... trabajo ...
if (++intentos > LIMITE) break; // vía de escape
}
Cuando probé esto en un proyecto que hacía scraping, me salvó de “espirales” donde la condición tardaba demasiado en romperse.
for brilla cuando conoces cuántas repeticiones quieres o cuando iteras índices:
for (let i = 0; i < n; i++) {
// bloque a repetir n veces
}
Piensa en for como una frase bien puntuada: empiezo en i=0; sigo mientras i<n; al final, i++.
Tu ejemplo clásico:
let suma = 0;
for (let i = 1; i <= 100; i += 2) {
suma += i;
}
console.log(suma);
Variante hacia atrás (útil para recorrer arrays cuando vas eliminando elementos):
for (let i = arr.length - 1; i >= 0; i--) {
// trabajar de derecha a izquierda
}
Aquí meto una cuña de experiencia: cuando expliqué este patrón a un equipo junior, entendieron por fin por qué “inicialización, condición y expresión final” importan tanto. Si una de las tres falla, el bucle no hace lo que esperas.
while es ideal cuando no sabes cuántas veces ocurrirá algo, pero sí bajo qué condición debería seguir:
let seguir = true;
while (seguir) {
// ...
seguir = decideSiContinuar(); // actualiza estado
}
Muy útil para validar entrada o para reintentos con límites:
let input;
let intentos = 0;
do {
input = obtenerValorUsuario();
} while (!esValido(input) && ++intentos < 3);
Aunque aquí usé do…while (lo veremos enseguida), la lógica de “seguir mientras no sea válido” es la esencia del while.
Con while es fácil olvidar actualizar el estado que alimenta la condición. Un truco que uso: en revisiones de código, busco explícitamente dónde cambia la variable que controla el while. Si no la encuentro en dos segundos, pido refactor.
En mi experiencia, los cuelgues por bucles infinitos “pueden dañar o hacer muy lenta” la app. Un break preventivo y logs de progreso cada X iteraciones me han ahorrado horas de depuración.
do…while ejecuta el bloque primero y luego verifica la condición:
let opcion;
do {
opcion = mostrarMenuYLeer();
} while (!["a","b","c"].includes(opcion));
Casos típicos:
Cuando enseño esto, repito: si necesitas una pasada garantizada (p. ej., pintar un primer frame), do…while encaja.
for…of recorre valores de cualquier iterable (arrays, strings, Maps, Sets):
for (const valor of miArray) {
console.log(valor);
}
Ventajas: legible, evita manejar índices cuando no los necesitas. Ideal para procesar elementos de una lista sin tocar posiciones.
for…in recorre propiedades enumerables de un objeto:
const usuario = { id: 1, nombre: "Ada" };
for (const clave in usuario) {
console.log(clave, usuario[clave]);
}
Advertencia: no lo uses para arrays si podrían tener propiedades añadidas o prototipos especiales; podrías iterar cosas que no son elementos.
Consejito práctico: si dudas entre dos, escribe un prototipo de 5 líneas con logs y revisa cuál te deja el código más claro (no solo más corto).
Prefiero código que se entienda. Si no hay evidencia de que el bucle es un cuello de botella, prioriza claridad (for…of sobre trucos crípticos). Cuando medí mejoras, muchas “micro-optimizaciones” daban ganancias marginales frente a cambiar el algoritmo o la ubicación del trabajo pesado.
Pequeño patrón que uso para probar ideas:
console.time("loop");
let total = 0;
for (let i = 0; i < 1e6; i++) total += i;
console.timeEnd("loop");
No es un benchmark científico, pero te da una sensación de impacto al iterar.
En mi experiencia, tener un “rail” mental (init–condición–update) y evitar infinitos me ha dado resultados estables y una UI fluida.
Reto: dada N, suma los números pares de 0 a N usando for. <details> <summary>Solución</summary>
function sumaPares(N) {
let s = 0;
for (let i = 0; i <= N; i += 2) s += i;
return s;
}
</details>
Reto: pide un valor hasta que pase esValido(x) o falles 3 veces. Usa do…while. <details> <summary>Solución</summary>
function pedirValido(obtener, esValido, max=3) {
let x, intentos = 0;
do {
x = obtener();
intentos++;
} while (!esValido(x) && intentos < max);
return esValido(x) ? x : null;
}
</details>
Reto: con for…in, devuelve [[clave, valor], ...] de un objeto. <details> <summary>Solución</summary>
function pares(obj) {
const out = [];
for (const k in obj) {
if (Object.prototype.hasOwnProperty.call(obj, k)) {
out.push([k, obj[k]]);
}
}
return out;
}
</details>
Los bucles son el motor de las tareas repetitivas en JavaScript. Si recuerdas el triángulo inicialización–condición–actualización y eliges la estructura adecuada (for, while, do…while, for…of, for…in) según el escenario, evitarás cuelgues, escribirás menos bugs y tu código será más legible. En mi experiencia, los infinitos son el enemigo: añade límites, break y logs, y todo fluirá.
No hay comentarios aún. ¡Sé el primero en comentar!
🍪 Utilizamos cookies para mejorar tu experiencia de navegación, analizar el tráfico del sitio y personalizar el contenido. Al continuar navegando, aceptas nuestro uso de cookies. Más información