Closures o Clausuras de Javascript

De Dos Ideas.
Saltar a: navegación, buscar

Closures o Clausuras de JavaScript

El concepto es "clausurar" el contexto en el que se ejecuta una funcion, a esta funcion se la denomina Closure.

Como funcionan?

En donde se encuentra una funcion dentro de otra, la funcion interna tiene acceso a las variables de la funcion externa.

function externa(x) {

 var variable = 3;
 function interna(y) {
   alert(x + y + (++variable));
 }
 interna(10);

}

externa(2);

Esto siempre dará un alert de 16, porque interna() puede acceder a la x que fue definida como argumento en externa() y tambien puede acceder a variable de externa().

Eso NO es un closure. Un closure es cuando se retorna la funcion interna y esta misma cierra sus variables externas antes de salir.

function externa(x) {

 var variable = 3;
 return function (y) {
   alert( x + y + (++variable) );
 }

} var interna = externa(2); // interna es ahora un closure. interna(10);

Tambien retornará un alert de 16, porque interna() todavia puede referenciar a x y variable, aunque ya no este directamente dentro del alcance de externa().

Sin embargo, como variable todavía esta siendo manejada dentro del closure interna(), va a continuar incrementandose cada vez que interna() sea llamada, a diferencia del ejemplo anterior.

Importante cuando trabajamos con Closures

En el último ejemplo x es un número literal y como todo literal en javascript, cuando se llame a externa() el numero x es copiado en la funcion como argumento.

Por otro lado, javascript siempre utiliza referencias cuando trabaja con Objetos. Por ejemplo, si llamamos a externa() con un objeto, el closure que retornará estará referenciado al objeto original.

function externa(x) {

 var variable = 3;
 return function (y) {
   alert(x + y + variable);
   x.unaProp = x.unaProp ? x.unaProp + 1 : 1;
   alert(x.unaProp);
 }

}

var edad = new Number(2); var interna = externa(edad); // interna es una closure referenciando al objeto edad. interna(10);

Como es esperado, cada llamada a interna() incrementará x.unaProp. Lo que puede no ser esperado es que x está referenciando al mismo objeto que guarda edad, luego de un par de llamadas a interna() edad.unaProp valdrá 2.

Ver también

Fuente