Closures en JavaScript

Closures en JavaScript

Este artículo explica los closures en JavaScript.

YouTube Video

Closures en JavaScript

En JavaScript, un 'closure' es uno de los conceptos muy importantes y poderosos. Al comprender los closures, puedes adquirir conocimientos útiles en muchas situaciones, como el comportamiento y el alcance de las funciones, así como el manejo asincrónico y de eventos en JavaScript. Aquí, explicaremos en detalle todo, desde la definición básica de los closures hasta ejemplos concretos y sus aplicaciones.

¿Qué es un Closure?

Un closure se refiere al mecanismo mediante el cual una función puede acceder a las variables en su alcance de creación, incluso cuando se llama fuera de ese alcance. Al utilizar los closures, las funciones se hacen capaces de 'recordar' continuamente las variables externas.

Los closures consisten en los dos elementos siguientes.

  1. Definición de la función (la función en sí misma)

  2. Ámbito en el que se define la función (variables y otras funciones fuera de la propia función)

En JavaScript, los closures son posibles porque las funciones tienen la capacidad de acceder a las variables dentro del alcance en el que fueron creadas.

Ejemplo Básico

Primero, veamos un ejemplo básico de un closure. En el siguiente código, outerFunction devuelve una función llamada innerFunction. El punto importante es que innerFunction puede acceder a la variable count definida dentro del alcance de outerFunction.

 1function outerFunction() {
 2    let count = 0;
 3
 4    function innerFunction() {
 5        count++;
 6        console.log(`Current count: ${count}`);
 7    }
 8
 9    return innerFunction;
10}
11
12const counter = outerFunction();
13counter(); // Current count: 1
14counter(); // Current count: 2
15counter(); // Current count: 3

Cómo Funcionan las Closures

Como se observa en el ejemplo anterior, count se conserva en innerFunction incluso después de que outerFunction se haya ejecutado. innerFunction puede seguir accediendo al alcance de outerFunction, y por lo tanto, count se actualiza dentro de innerFunction. Este es el mecanismo básico de un closure.

innerFunction es la función que se asigna a la variable counter, y podemos observar que el estado de count se conserva, incluso después de que outerFunction haya finalizado su ejecución. Esto se debe a que JavaScript 'recuerda' continuamente el alcance en el momento de la definición de la función.

Aplicación: Closures como Variables Privadas

Los closures pueden ser utilizados como 'variables privadas' en la programación orientada a objetos. Normalmente, en JavaScript, las propiedades de los objetos son accesibles directamente desde el exterior, pero al usar closures, es posible evitar la manipulación directa de las variables dentro del alcance de la función desde el exterior.

En el siguiente ejemplo, la función createCounter utiliza un closure para crear un contador y devuelve un contador con una variable privada count.

 1function createCounter() {
 2    let count = 0;
 3
 4    return {
 5        increment: function() {
 6            count++;
 7            console.log(`Count: ${count}`);
 8        },
 9        decrement: function() {
10            count--;
11            console.log(`Count: ${count}`);
12        },
13        getCount: function() {
14            return count;
15        }
16    };
17}
18
19const myCounter = createCounter();
20myCounter.increment(); // Count: 1
21myCounter.increment(); // Count: 2
22myCounter.decrement(); // Count: 1
23console.log(myCounter.getCount()); // 1

En este ejemplo, count está dentro del alcance de la función createCounter, por lo que no puede ser accesada directamente desde el exterior. Sin embargo, puede manipularse a través de los métodos increment y decrement. De esta manera, usando closures, puedes incorporar el concepto de variables privadas en JavaScript.

Ejemplos prácticos de closures

Combinación con funciones de retrollamada

Los closures se utilizan a menudo en combinación con funciones de callback para manejar el procesamiento asíncrono. Por ejemplo, consideremos un ejemplo que utiliza un temporizador.

 1function startTimer(duration) {
 2    let timeLeft = duration;
 3
 4    function countdown() {
 5        console.log(`Time left: ${timeLeft} seconds`);
 6        timeLeft--;
 7
 8        if (timeLeft >= 0) {
 9            setTimeout(countdown, 1000);
10        }
11    }
12
13    countdown();
14}
15
16startTimer(5);
17// Time left: 5 seconds
18// Time left: 4 seconds
19// Time left: 3 seconds
20// Time left: 2 seconds
21// Time left: 1 second
22// Time left: 0 seconds

En este ejemplo, la función countdown accede a la variable timeLeft dentro del ámbito de startTimer. De esta manera, los closures son muy útiles para el procesamiento asíncrono como temporizadores, ya que mantienen el estado de las variables a lo largo del tiempo.

Manejadores de eventos

Los closures también son convenientes al configurar manejadores de eventos. En el siguiente ejemplo, se utiliza un closure para registrar el número de veces que se pulsa un botón.

 1function setupClickCounter(buttonId) {
 2    let clickCount = 0;
 3
 4    const button = document.getElementById(buttonId);
 5    button.addEventListener('click', function() {
 6        clickCount++;
 7        console.log(`Button clicked ${clickCount} times`);
 8    });
 9}
10
11setupClickCounter('myButton');

En este caso, clickCount aumenta con cada clic y su valor se conserva. Al usar closures, puedes asignar un contador independiente a cada botón.

Conclusión

Los closures son un concepto que simboliza la flexibilidad y el poder de JavaScript. Contienen variables encerradas dentro del ámbito de una función y permiten operar con esas variables a través de funciones accesibles externamente. Al comprender y utilizar este mecanismo, puedes adquirir técnicas más avanzadas en la programación con JavaScript.

Los closures se aplican en diversas situaciones, desde el manejo de eventos y el procesamiento asíncrono hasta incluso pseudoimplementaciones de programación orientada a objetos.

Puedes seguir el artículo anterior utilizando Visual Studio Code en nuestro canal de YouTube. Por favor, también revisa nuestro canal de YouTube.

YouTube Video