Closures en JavaScript: los ejemplos que siempre confunden
Mario Rojas
1 min de lectura

Un closure es una función que recuerda las variables del lugar donde fue creada, aunque ese lugar ya haya terminado de ejecutarse. Suena abstracto, pero lo usas todos los días sin notarlo.
El ejemplo básico
function crearContador() {
let cuenta = 0;
return () => ++cuenta;
}
const contador = crearContador();
contador(); // 1
contador(); // 2
crearContador ya terminó, pero la función que devolvió sigue teniendo acceso a cuenta. Esa variable vive mientras exista alguien que la use.
El clásico que confunde: var en un bucle
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 100);
}
// 3, 3, 3
Las tres funciones comparten la misma i, y cuando se ejecutan el bucle ya terminó. Con let, cada vuelta crea una variable nueva:
for (let i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 100);
}
// 0, 1, 2
Donde los usas sin saberlo
- Hooks de React: cada render crea funciones nuevas que "capturan" el estado de ese render. Por eso a veces un
setIntervalve un valor viejo (el famoso stale closure). - Datos privados: el contador de arriba no expone
cuenta; solo se puede modificar a través de la función. - Funciones fábrica:
crearValidador(min)devuelve una función que ya conocemin.
Lo que me ayudó a entenderlo
Deja de pensar que una función solo lleva su código. Lleva también una "mochila" con las variables que ve a su alrededor. Cuando algo se comporta raro, pregúntate: ¿qué variable está en la mochila y cuándo se guardó?