Closures o Clausuras de Javascript
Contenido
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.