Cargando...

Closures

Ya conoces el ámbito (scope): desde aquí, qué nombres son visibles. Un paso más: una función interna puede seguir usando un nombre exterior después de que termine la llamada exterior. Ese vínculo duradero es un closure.

Qué significa un closure

Se forma un closure cuando una función se crea dentro de otra y más tarde sigue alcanzando los enlaces de la exterior. La llamada exterior puede haber terminado; la interna aún «recuerda» esos nombres. No escribes la palabra closure en el código: escribes funciones anidadas y JavaScript mantiene vivos los enlaces exteriores necesarios.

Tres piezas a mirar

📊 Función exterior, enlace y función interior

Pieza Rol Pista para principiantes
función exterior se ejecuta una vez (o más) y a menudo devuelve una interior la llamada de «preparación»
enlace exterior un parámetro o let / const en la exterior el valor que la interior aún necesita
función interior usa ese enlace cuando la llamas después la función que guardas

Si puedes señalar esas tres, explicas casi cualquier ejemplo de closure para principiantes. La sorpresa no es el anidamiento: es que el enlace exterior sigue siendo útil tras el return exterior.

Función interior lee un nombre exterior

javascript
function makeLine(title) {
function show() {
console.log(title);
}
show();
}
makeLine("Shop");

Durante la llamada, la interior mira hacia afuera

show no tiene un title local. La búsqueda camina hacia afuera hasta makeLine y encuentra el parámetro. Eso es ámbito anidado normal. El closure da un paso más: guarda show (o su gemela) para después, cuando makeLine ya haya vuelto.

Conserva la función interior tras return

javascript
function makeLine(title) {
return function show() {
console.log(title);
};
}
let printShop = makeLine("Shop");
printShop();

Termina la llamada exterior — la memoria permanece

makeLine("Shop") devuelve una función. Cuando llamas printShop después, aún imprime Shop. El parámetro title de esa llamada terminada sigue alcanzable. Esa captura duradera es el closure.

Fábrica pequeña de saludo

javascript
function makeGreeter(name) {
return function () {
return "Hello, " + name;
};
}
let hiSara = makeGreeter("Sara");
console.log(hiSara());

Las fábricas devuelven una función lista

makeGreeter es una fábrica pequeña: una llamada exterior, una función a medida de vuelta. hiSara siempre saluda a Sara porque cerró sobre ese name. Cambia el argumento de makeGreeter y obtienes otro saludador: mismo patrón, memoria nueva.

Contador que recuerda

javascript
function makeCounter() {
let n = 0;
return function () {
n = n + 1;
return n;
};
}
let tick = makeCounter();
console.log(tick());
console.log(tick());

Estado casi privado con un contador

n vive en la función exterior. El código de fuera no toca n directamente: solo la función devuelta puede. La primera llamada devuelve 1, la segunda 2. El contador «recuerda» sin una variable global.

Dos contadores, dos memorias

javascript
function makeCounter() {
let n = 0;
return function () {
n = n + 1;
return n;
};
}
let a = makeCounter();
let b = makeCounter();
console.log(a());
console.log(a());
console.log(b());

Cada llamada exterior tiene su memoria

a y b vienen de llamadas makeCounter() distintas, así que cada una tiene su propio n. Dos avances en a no hacen que b empiece a mitad. Los closures no comparten un saco de estado automáticamente salvo que compartas a propósito un enlace exterior.

Mostrar un valor cerrado en la página

Crea un saludador con la fábrica, llámalo una vez y pon la cadena devuelta en un párrafo.

Demo de página con closure

html
<!DOCTYPE html>
<html>
<head>
<title>closures — page</title>
</head>
<body>
<p id="msg">…</p>
<script>
function makeGreeter(name) {
return function () {
return "Hello, " + name;
};
}
let hi = makeGreeter("Omar");
let box = document.getElementById("msg");
box.textContent = hi();
</script>
</body>
</html>

El párrafo muestra Hello, Omar. La llamada exterior terminó; hi aún conoce name. Cambia solo la cadena pasada a makeGreeter, actualiza y lee la nueva línea. Siguiente: objetos — valores relacionados bajo un solo nombre.

Práctica

  1. Escribe una función que devuelva una interior que registre un parámetro exterior.
  2. Guarda esa función devuelta y llámala tras terminar la llamada exterior.
  3. Crea makeGreeter("Lina") y registra la cadena que devuelve.
  4. Crea un contador; llámalo dos veces y confirma 1 y luego 2.
  5. Crea dos contadores; avanza solo el primero dos veces y comprueba que el segundo empieza en 1.
  6. En la demo HTML cambia solo el argumento del nombre, actualiza y lee el párrafo.

Tropezones frecuentes

  • Suponer que los locales exteriores desaparecen al instante del return — la interior aún puede verlos
  • Esperar que cada makeCounter() comparta un solo n — cada llamada suele tener su memoria
  • Creer que «closure» significa solo la palabra return — return puede devolver la interior, pero la memoria es el enlace cerrado
  • Poner todo valor recordado en el objeto global «para simplificar»
  • Esperar aquí la lección completa de objetos — agrupar propiedades bajo un valor es la página siguiente

Resumen

  • Un closure permite que una función interior siga usando nombres exteriores tras la llamada exterior
  • Escribes funciones anidadas; JavaScript mantiene vivos los enlaces necesarios
  • Las fábricas devuelven una función a medida que recuerda los valores de preparación
  • Los contadores ocultan un n privado tras la función devuelta
  • Llamadas exteriores separadas suelen significar memorias separadas
  • La página puede mostrar una cadena producida por un nombre cerrado
  • Siguiente: objetos — valores relacionados bajo un nombre

🧠 Pon a Prueba tu Conocimiento

Listo para Empezar

Pon a Prueba tu Conocimiento

Ponte a prueba con este cuestionario interactivo y descubre qué tan bien entiendes el tema

❓
8
Preguntas
🎯
70%
Para Aprobar
♾️
∞
Tiempo
🔄
∞
Intentos

📝 Instrucciones

  • Lee cada pregunta cuidadosamente
  • Selecciona la mejor respuesta para cada pregunta
  • Puedes repetir el quiz tantas veces como quieras
  • Tu progreso se mostrará en la parte superior