¿Por qué son importantes los cierres en JavaScript?

Las variables de JavaScript pueden pertenecer al ámbito local o global. Las variables privadas pueden hacerse posibles con los cierres . . Un cierre es una función interna que tiene acceso a las variables de la función externa (envolvente): cadena de alcance. Son un mecanismo de abstracción que le permite separar las preocupaciones de manera muy limpia.

Creemos una función que devuelva la función. Esta función cierra el contexto del ámbito primario y recuerda el valor de x. Después de llamar a “var a = sum (4);”, “a” equivale a “return function (y) {return x + y;}”. Pero sabe lo que es x. Entonces “a” en realidad es igual a “función de retorno (y) {return 4 + y;}”. Entonces, cuando llamamos “var b = a (3);”, estamos obteniendo 7 en respuesta como se esperaba.

var sum = función (x) {
función de retorno (y) {
devolver x + y;
}}
var a = suma (4);
var b = a (3);
console.log (b) // 7;

Los cierres hacen que el código sea más compacto, legible y hermoso y promueven la reutilización funcional. Saber cómo y por qué funcionan los cierres elimina la incertidumbre en torno a su uso.

Aquí hay un ejemplo simple que demuestra la importancia y utilidad de los cierres en JavaScript:

Digamos que tiene una página web simple que contiene un botón. Cada vez que se hace clic en ese botón, desea mostrar una ventana emergente (alerta) que contiene un número creciente. Entonces, en el primer clic, el cuadro de alerta contendrá 0, en el segundo clic 1, y así sucesivamente.

El enfoque más simple sería usar una variable global para almacenar el contador:

let globalCounter = 0;
botón const = document.getElementById (“btn”);
button.addEventListener (“clic”, función () {
alerta (globalCounter ++);
});

Esto funcionará, pero el uso de una variable global es generalmente una mala idea. Si alguna otra parte del código intenta usar un global que tenga el mismo nombre, obtendrá una excepción (con let o const ), o peor aún, un comportamiento extraño e impredecible (con var ).

OK, entonces, JavaScript está orientado a objetos, ¿verdad? ¿Por qué no poner el contador en una propiedad de objeto?

const obj = {
counterProperty: 0,
haga clic en () {
alerta (this.counterProperty ++);
}
};
botón const = document.getElementById (“btn”);
button.addEventListener (“clic”, obj.click);

Desafortunadamente, esto no funcionará en absoluto. El problema es que este valor dentro de la propiedad click se establecerá en el elemento HTML del botón en lugar de obj . Y no hay counterProperty en el elemento del botón.

Finalmente, implementemos esto usando un cierre:

función clickMaker () {
let scopedCounter = 0;
función de retorno () {
alerta (scopedCounter ++);
};
}
botón const = document.getElementById (“btn”);
button.addEventListener (“clic”, clickMaker ());

La función clickMaker devuelve una función interna, y esa función interna lleva su alcance con ella, como un cierre. Esto significa que la función interna obtiene su propia instancia de scopeCounter , a la que solo puede acceder. Y puede usar clickMaker para realizar funciones adicionales, cada una con su propia instancia.

Obviamente, este ejemplo es un poco artificial, pero el concepto es muy real y muy, muy útil. Además, podríamos haber hecho que el segundo intento funcione usando .bind , pero eso es realmente un atajo para crear un cierre.

Los cierres nos permiten vincular una función a cualquier variable en el alcance externo para que podamos usarlas en un momento posterior.

Esto es particularmente importante en Javascript donde (tradicionalmente) no tenemos variables privadas que puedan abstraer la funcionalidad del usuario.