Closures: definición y usos prácticos
Un closure es una función que “recuerda” el entorno léxico en el que fue creada, incluso después de que ese entorno haya dejado de existir.
En otras palabras, una función interna tiene acceso a:
- Sus variables propias
- Las variables de su función padre
- Las variables globales
Esto ocurre porque en JavaScript, las funciones son objetos de primera clase y mantienen una referencia viva a su contexto de creación (scope).
Ejemplo técnico
function outer() {
const outerVar = 'visible';
return function inner() {
console.log(outerVar); // 'visible'
};
}
const closureFn = outer();
closureFn(); // aún puede acceder a outerVar
Aquí, inner() es un closure que captura outerVar incluso después de que outer() terminó su ejecución.
Usos prácticos
-
Encapsulamiento y privacidad de datos
function counter() {
let count = 0;
return {
increment: () => ++count,
decrement: () => --count,
getCount: () => count,
};
}
const c = counter();
c.increment(); // 1
c.increment(); // 2
c.getCount(); // 2La variable
countno es accesible desde afuera, solo mediante métodos seguros. -
Funciones parciales - currying
function greet(greeting: string) {
return function (name: string) {
return `${greeting}, ${name}!`;
};
}
const sayHello = greet('Hola');
sayHello('David'); // 'Hola, David!'Se guarda el estado
greetingen un closure y se reutiliza -
Funciones asíncronas en bucles
for (let i = 1; i <= 3; i++) {
setTimeout(() => {
console.log(`Contador: ${i}`);
}, i * 1000);
}
// Imprime 1, 2, 3 en segundos consecutivos gracias al cierre sobre `i`Gracias a
let(y closures), cada función conserva su valor correcto dei. -
Factories de funciones
function makeMultiplier(factor: number) {
return function (x: number) {
return x * factor;
};
}
const double = makeMultiplier(2);
const triple = makeMultiplier(3);
double(5); // 10
triple(5); // 15Crea funciones personalizadas reutilizando lógica común.
-
Creación de módulos o patrones tipo módulo
Closures son la base de patrones como el Módulo Revelado o Módulo IIFE,para mantener código organizados y seguro:
const userModule = (() => {
let username = 'David';
return {
getUsername: () => username,
setUsername: (name: string) => (username = name),
};
})();
userModule.getUsername(); // David
userModule.setUsername('Ana');
userModule.getUsername(); // AnaEl estado interno (
username) está protegido dentro del closure. -
Callbacks con contexto guardado
function onClickLogger(buttonId: string) {
return () => console.log(`Click en ${buttonId}`);
}
document.getElementById('btnSave')?.addEventListener('click', onClickLogger('Guardar'));Closures permiten pasar funciones con un estado recordado como callbacks. En el anterior ejemplo, cada botón puede tener su logger personalizado sin compartir estado.
-
Control de acceso por niveles o validaciones
function secureAccess(userRole: string) {
return function (resource: string) {
if (userRole === 'admin') {
return `Accediendo a ${resource}`;
} else {
return `Acceso denegado a ${resource}`;
}
};
}
const accessForAdmin = secureAccess('admin');
const accessForUser = secureAccess('user');
accessForAdmin('config'); // Accediendo a config
accessForUser('config'); // Acceso denegado a configPermiten configurar funciones con condiciones internas persistentes.
Uso de Closure
Prueba de concepto
function createSecret(secret: string) {
return function reveal() {
return `El secreto es: ${secret}`;
};
}
const getSecret = createSecret('JS es poderoso');
getSecret(); // El secreto es: JS es poderoso
¿Cómo se conserva el entorno léxico en un closure?
function outer() {
const mensaje = 'Hola Closure';
return function inner() {
console.log(mensaje); // aún accede a mensaje
};
}
const fn = outer(); // outer() ya terminó, pero...
fn(); // 'Hola Closure'
Aunque outer() ya se ejecutó, su contexto (scope) no es recolectado por el garbage collector, porque la función inner() aún lo necesita.
Referencias
- Flanagan, D. (2020). JavaScript: The Definitive Guide (7th ed.). O’Reilly Media.
- Mozilla Developer Network. (s.f.). Closures.
- Crockford, D. (2008). JavaScript: The Good Parts. O’Reilly Media.
- Google. (s.f.). JavaScript Style Guide.
- Zakas, N. C. (2012). Maintainable JavaScript: Writing Readable Code. O’Reilly Media.