Saltar al contenido principal
Codigo Heroe
Tarea anterior
Introducción a los eventos18/21
A la lista de tareas
  1. 1. Eventos del usuario
  2. 2. Añadir un manejador de eventos
  3. 3. Sintaxis de los manejadores
  4. 4. Acciones predeterminadas
  5. 5. Funciones como argumentos
  6. 6. Eliminar clases con classList.remove()
  7. 7. Eventos de teclado
  8. 8. Identificar una tecla
  9. 9. Cerrar una ventana con ESC
  10. 10. Seleccionar los elementos de una galería
  11. 11. Añadir manejadores en un ciclo
  12. 12. Cambiar el src de una imagen
  13. 13. Depurar un manejador
  14. 14. Ámbito local
  15. 15. Ámbito global
  16. 16. Cambiar variables externas
  17. 17. Funciones dentro de funciones
  18. 18. Cierres
  19. 19. Un cierre en cada llamada
  20. 20. Usar cierres en los manejadores
  21. 21. Completar la galería
Siguiente tarea
  • Matriz de skills
  • Cursos
  • Registro
  • Iniciar sesión

Loading…
En unos segundos, estará listo.

  • Teoría
  • Teoría

Cierres

El código funciona. ¿Cuál es el secreto de esta expresión y qué significa?

var collectContainer = function () {
  var food = 'pasta';
  var eatDinner = function () {
    console.log('Comí ' + food);
  }
  return eatDinner;
};

var schoolkid = collectContainer();
schoolkid();
// Muestra: Comí pasta

Queremos que la función utilice una variable propia que no dependa de los cambios de la variable global, y obtener el resultado más tarde. Algo parecido ocurre con los manejadores: los creamos, pero esperamos a un evento para ejecutarlos. En nuestro ejemplo, preparamos un recipiente con pasta para poder comerla sin importar qué haya en el comedor.

El código sigue estos pasos: llamamos a collectContainer → collectContainer devuelve eatDinner → llamamos a eatDinner.

Creamos una función dentro de otra y, con ello, un ámbito dentro de otro. eatDinner tiene su propio ámbito y utiliza food, que está declarada en el ámbito de collectContainer, exterior al de eatDinner.

eatDinner no encuentra una variable local llamada food y la busca en el ámbito exterior, el de collectContainer. Allí encuentra la variable cuyo valor es 'pasta'. La función conserva el acceso a esa variable incluso después de que termine la llamada a collectContainer.

¡Un momento! Mostramos schoolkid en la consola y no había pasta por ningún lado.

var collectContainer = function () {
  var food = 'pasta';
  var eatDinner = function () {
    console.log('Comí ' + food);
  };
  return eatDinner;
};

var schoolkid = collectContainer();
console.log(schoolkid);
// Muestra: function () { console.log('Comí ' + food); }

Así es. El código de la función no cambia: junto con ella se conserva el acceso al entorno donde fue creada. A esto lo llamamos cierre, o closure: una función junto con el acceso a las variables de su entorno exterior. La función no guarda una copia congelada de sus valores; al ejecutarse, utiliza el valor que tiene cada variable en ese momento.

En nuestro ejemplo, eatDinner forma un cierre con acceso a la variable local food de collectContainer.

Gracias a ese cierre, eatDinner sigue accediendo a la misma variable local cuando la llamamos más tarde. En este ejemplo nadie cambia esa variable, así que sigue valiendo 'pasta'. La variable global también se llama food, pero es otra variable. Es como si tu mamá te pidiera comprar papas al pasar por la tienda: puedes seguir con tus cosas y recordar el encargo al llegar.

Comprobemos que el cierre permite comer la pasta del recipiente aunque cambie la comida del comedor.

  • script.js
JavaScript
var food = 'ensalada'; var collectContainer = function () { var food = 'pasta'; var eatDinner = function () { console.log('Comí ' + food); }; return eatDinner; }; var schoolkid = collectContainer();
Consola

El código ha cambiado, haga clic en "Ejecutar" o active la ejecución automática.

Resultado de la ejecución

ObjetivosRealizado
0
    1. Debajo de la declaración de schoolkid, llama a la función guardada en esa variable.
    2. Debajo, reasigna la variable globalfood con el valor 'caldo'.
    3. Después, vuelve a llamar a la función schoolkid.
    Codigo Heroe

    © 2023-2026, codigoheroe.com