Closures y Ámbito Léxico en JavaScript

Clase 25 de 55Curso de Fundamentos de JavaScript

Contenido del curso

Introducción a JavaScript

Estructuras de Control y Lógica

Manipulación de Arrays

Programación Orientada a Objetos

Asincronía en JavaScript

Resumen

Comprender cómo una función puede recordar variables de su entorno exterior, incluso después de haberse ejecutado, es fundamental para escribir código flexible y potente en JavaScript. Esto es exactamente lo que logran los closures, y dominar este concepto marca una diferencia importante en la forma de estructurar aplicaciones.

¿Qué es un closure y cómo se relaciona con el ámbito léxico?

Un closure es una función que tiene acceso a variables de un ámbito externo, incluso después de que esa función externa ya haya terminado de ejecutarse [0:08]. Para comprender esta idea es necesario conocer el ámbito léxico (lexical scope): cuando una función se declara, se crea un ámbito léxico que le permite acceder tanto a sus propias variables como a las de ámbitos superiores [0:22].

En la práctica esto significa que si dentro de una función externa (outer function) se define una función interna (inner function), esta última puede leer y utilizar las variables de la primera.

¿Cómo se ve un closure en código?

El ejemplo más directo consiste en crear una función outerFunction con una variable outerVariable que contiene el texto "I am from Outer function" [0:42]. Dentro de ella se define innerFunction, que ejecuta un console.log de esa variable externa y luego se retorna [1:06].

javascript function outerFunction() { const outerVariable = "I am from Outer function";

function innerFunction() { console.log(outerVariable); }

return innerFunction; }

const closureExample = outerFunction(); closureExample();

Al ejecutar el programa, la consola muestra I am from Outer function [1:50]. Esto confirma que innerFunction accedió a la variable de su función contenedora, y eso es precisamente un closure.

¿Por qué hay que tener cuidado con el uso de memoria?

Los closures conservan referencias a las variables externas, lo que implica consumo de memoria. Para ilustrarlo se crea una función createCounter con una variable count inicializada en cero [2:16]. Internamente retorna una función que incrementa count con count++ y lo imprime con console.log [2:32].

javascript function createCounter() { let count = 0;

return function () { count++; console.log(count); }; }

const counterA = createCounter(); counterA(); // 1 counterA(); // 2

const counterB = createCounter(); counterB(); // 1

Cada llamada a createCounter genera un ámbito léxico independiente [3:15]. Por eso counterA llega a 2 mientras counterB arranca en 1: cada instancia almacena su propio valor de count en memoria. Esto demuestra que, aunque los closures son muy útiles, conviene no abusar de ellos para evitar un consumo excesivo de recursos [3:30].

¿Cómo manejar diferentes contextos con closures?

Otro uso práctico es generar funciones con contextos distintos a partir de una misma estructura. Se crea una función other con una variable message que contiene "Hello, " [3:50]. Dentro se define inner, que recibe un parámetro name y lo concatena con el mensaje externo [4:18].

javascript function other() { const message = "Hello, ";

function inner(name) { console.log(message + name); }

return inner; }

const closureA = other(); const closureB = other();

closureA("Alice"); // Hello, Alice closureB("Bob"); // Hello, Bob

Al ejecutar se obtiene Hello, Alice y Hello, Bob [5:06]. Cada closure mantiene su propio contexto pero comparte la misma lógica interna, lo que permite crear funciones flexibles y reutilizables.

¿Qué ventajas ofrecen los closures en la práctica?

  • Permiten trabajar con diferentes ámbitos dentro de una misma estructura de funciones.
  • Facilitan la creación de funciones que recuerdan estado entre ejecuciones, como contadores o acumuladores.
  • Hacen posible generar múltiples contextos a partir de una sola función base, personalizando el comportamiento con parámetros.
  • Su uso debe ser consciente y medido, ya que cada closure retiene referencias en memoria que no se liberan automáticamente [5:30].

Si ya has experimentado con closures en tus proyectos o tienes dudas sobre cómo aplicarlos de forma eficiente, comparte tu experiencia en los comentarios.