Los closures en JavaScript son una característica fundamental del lenguaje que permite a las funciones recordar el estado de su entorno de ejecución, incluso después de que la función haya sido invocada. Esto permite a las funciones mantener un estado privado y protegido de variables y funciones internas, lo que proporciona una mayor flexibilidad y seguridad en el código.
Un closure se crea cuando una función es declarada dentro de otra función. La función interna tiene acceso al ámbito de la función externa, lo que significa que puede acceder a las variables y funciones declaradas dentro de la función externa. Además, un closure también tiene acceso a las variables y funciones globales.
Observa el siguiente ejemplo de la función counter. La función externa crea una variable privada "count" y una función interna "increment" que incrementa el valor de "count" y devuelve el valor actual.
En este ejemplo, la función "counter" es el closure y tiene acceso a la variable privada "count" y la función interna "increment". Al asignar la función "contador" a la variable "myCounter" y luego llamar a la función "myCounter", se está utilizando el closure para acceder a la variable "count" y modificar su valor cada vez que se llama a la función "increment". Esto permite mantener un estado interno privado en la función "contador" y evitar conflictos con otras variables con el mismo nombre en el ámbito global.
Además de ayudar a mantener el estado privado, los closures también son útiles para crear funciones genéricas y reutilizables, ya que pueden ser parametrizadas con variables y funciones declaradas en su entorno de ejecución. Por ejemplo, una función que toma una función y un valor como argumentos y devuelve una nueva función que aplica el valor a la función original.
En este ejemplo, la función "multiplyBy" es un closure que toma un factor como argumento y devuelve una nueva función que multiplica el valor dado por el factor. Al asignar la función "multiplicador" con un factor específico a la variable "doble", se está utilizando el closure para parametrizar la función con un valor específico y crear una nueva función reutilizable que siempre multiplica el valor dado por 2, por 3 o cualquier otro número.
Hoy quiero hablarles sobre uno de los conceptos más interesantes en JavaScript: los closures.
.
Un closure es una función que guarda referencias a variables en su entorno léxico, incluso después de que la función ha sido devuelta. Esto significa que una función que se define dentro de otra función (la función interna) tiene acceso a las variables de la función externa (el ámbito léxico).
.
En términos más simples, un closure permite que una función acceda a variables que no están dentro de su propio ámbito. Esto es útil para crear funciones más flexibles y reutilizables.
.
Ejemplo:
function sumar(a) { // función declarativa que recibe un parámetro 'a'
return function(b) { // rotorno de función anónima que recibe un parámetro 'b'
return a + b; // esa función retorna la suma de 'a' y 'b'
}
}
// declaración de variables con llamadas de función 'sumar' y un parámetro 'a'
let suma1 = sumar(5);
let suma2 = sumar(10);
console.log(suma1(2)); // devuelve 7
console.log(suma2(3)); // devuelve 13
En este ejemplo, sumar() es una función que devuelve otra función. La función interna es el closure, y tiene acceso a la variable a de la función externa.
.
Al llamar a sumar(5), se crea un closure que guarda el valor de a como 5. Luego, al llamar a suma1(2), la función interna suma 2 al valor de a (5) y devuelve 7.
.
De manera similar, al llamar a sumar(10), se crea otro closure que guarda el valor de a como 10. Luego, al llamar a suma2(3), la función interna suma 3 al valor de a (10) y devuelve 13.
Un video recomendado para entender mejor el concepto
Excelente aporte. Me encantó el ejemplo, muy bien explicado.
Contador me imagino que sea counter intercambio de idioma jijij
Hahahaha si! Ahí se han equivocado con el idioma.
Una cuestión que me costó entender en el primer ejemplo es por qué la variable count no se inicializa a 0 cada vez que se llama a la variable myCounter dado que existe la linea
let count =0;
Mi interpretación después de un buen rato razonando, es que cuando se ejecuta
const myCounter =counter();
básicamente lo que sucede es que se inicializa count=0, se devuelve la función increment() y se almacena en la variable myCounter. Por lo tanto esta ultima variable es igual a increment(), por lo que llamar a myCounter() es exactamente lo mismo que llamar a increment(). En este caso existe una variable guardada en memoria bajo el nombre count, y cada vez que se llama a myCounter (o increment), este espacio se sobreescribe y es por eso que el output de la función cambia.
Por favor corríjanme si alguien tiene un conocimiento más verídico de lo que sucede detrás de la ejecución del script. Gracias
arreglen el typo en "contador", creo que deberia haber sido counter
si hay un typo detected!
25/89 Closures
Es una característica que permite a las funciones mantener un estado interno privado y protegido de variables y funciones externas. Los closures se crean cuando una función es declarada dentro de otra función y tienen acceso al ámbito de la función extenera, incluyendo las variables y funciones genéricas y reutilizables, que pueden ser parametrizadas con variables y funciones declaradas en su entorno de ejecución.
Un ejemplo de closure en JavaScript es la función “counter, que crea una variable privada count y devuelve el valor actual cada vez que se llama. Al asignar la función contador a una variable y luego llamar a la funciín varias veces, se está utilizando el closure para acceder a la variable count y modificar su valor cada vez que se llama a la función increment.
Otro ejemplo es la funciín multiplyBy que toma un factor como argumento y devuelve una función que multiplica el valor dado por el factor. Al asignar la función “multiplicador” con un factor específico a una variable y luego llamar ala función varias veces con diferentes valores, se está utilizando el closure para parametrizar la función con un valor específico y crear una nueva función reutilizable que siempre multiplica el valor dado por ese factor.
Ej createCounter para crear un contador personalizado a partir de un valor inicial:
EJ función para contar la cantidad de veces que se llama a una función utilizando un clousure:
functioncountCalls(fn){let count =0;returnfunction(...args){ count++;console.log(`La función ha sido llamada ${count} veces.`);returnfn(..arg);}}functiongreet(name){console.log(`Hola, ${name}!);}const countedGreet =countCalls(greet);countedGreet('Juan');// Output: Hola, Juan! //La función ha sido llamada 1 vezcountedGreet('Maria');// Output: Hola, Maria! // La función ha sido llamada 2 veces
En el ejemplo indica que counter es el closure, pero me queda la duda la función increment no seria la closure, ya que tiene acceso a la variable count fuera de su bloque.
Tienes razón, en el curso de Closures se indica que el Closure se crea al crear una función interna y que conforma la suma de esa función con el scope interno dentro de la función externa.
Se me hizo complicado entenderlo.
1.- La función principal se resuelve y mantiene su estado.
2.- La función que se retorna se guarda en la variable a la que lo asignes con el estado.
3.- Podemos usar la variable que contiene a la función secundaria para hacer cosas.
creo que toca practicar mas, a ver cuando se necesitan usar este tipo de funciones...