Cuando una función utiliza una variable la cual fue declarada fuera de dicha función.
var imprimir = (function(){
var h = 'hola'; /* Se define una variable */
function imprimirH(){
console.log(h); /* <- Closure: Se conserva el acceso a la variable h */
}
return imprimirH;
})();
imprimir(); // => 'hola'
El acceso a las variables fuera del ámbito léxico inmediato crea un closure/cierre. En otras palabras, se forma un closure cuando una función anidada se define dentro de otra función, permitiendo el acceso a las a las variables de las función externa. El hecho de retornar una función anidada permite mantener el acceso a las variables locales, argumentos y declaraciones de funciones internas de la función externa.
Esta encapsulación nos permite ocultar y preservar el contexto de ejecución de ámbitos externos, al mismo tiempo expone una interfaz pública que pueda ser compartida y reutilizada en el futuro.
function encapsulacion() {
var _unaPropiedadPrivada = 'una propiedad privada';
function _metodoPrivado(arg){
return 'Soy un método privado alterando ' + arg;
}
return function metodoPublico() {
return _metodoPrivado(_unaPropiedadPrivada);
}
}
var obtenerVariable = encapsulacion();
obtenerVariable() // 'Soy un método privado alterando una propiedad privada'.
Uno de los tipos más populares de closures es el famoso patrón de módulo; el cual permite emular miembros públicos, privados y privilegiados:
El patrón de módulo se definió para proporcionar algo parecido a la encapsulación privada y pública de clases de la ingeniería convencional de sofware.
Relación entre Patrón de Módulo y Cierres
El patrón de módulo encapsula "privacidad", estado y organización utilizando cierres/closures. Proporciona una manera de envolver y mezclar variables y métodos públicos y privados también.
Interfaz
Proteje a ciertas piezas de filtrarse en el ámbito global y de chocar accidentalmente con alguna otra interfaz. Con el patrón de módulo, solamente se devuelve una API pública, manteniendo todo lo demás dentro del closure privado.
Como vimos, el patrón de módulo expone una interfaz que otras partes de nuestra aplicación pueden utilizar. Este patrón es muy similar a una expresión funcional inmediatamente-invocada (IIFE), excepto que en nuestro devolvemos un objeto en lugar de una función.
¿Que permite () al final de la función?
El módulo actúa como si fuera un singleton, corre tan pronto como el compilador lo interpreta, por eso, la apertura y cierre de paréntesis al final de la función. Los únicos miembros disponibles fuera del contexto de ejecución del closure son sus métodos y propiedades ubicadas en el objeto público que se retorna. Sin embargo, todas las propiedades y métodos privados vivirán toda la vida de la aplicación mientras el contexto de ejecución se preserve, esto signifca que las variables pueden llegar a ser objeto de interacción via los métodos públicos.
IIFE - Expresión de Función Inmediatamente-Autoinvocada
Otro tipo de closure es IIFE, que no es más que una función anónima auto-invocado que corre en el contexto de window:
(function(window) {
var _unaPropiedadPrivadaa;
function _unMetodoPrivado() {
console.log('_unMetodoPrivado');
}
window.Module = {
public: function() {
// do something
}
};
})(this);
Este tipo de expresión es útil cuando se trata de preservar el espacio de nombres global así como las variables declaradas dentro del cuerpo de la función serán locales al closure y viviran a lo largo de todo su tiempo de ejecución. Este es un tipo bastante popular de encapsulado de código fuente que usan mucho las aplicaciones y los frameworks también, por lo general se usa para exponer una sola interfaz global con la cual se pueda interactuar.
Closure
Cuando una función utiliza una variable la cual fue declarada fuera de dicha función.
El acceso a las variables fuera del
ámbito léxico
inmediato crea unclosure/cierre
. En otras palabras, se forma unclosure
cuando una función anidada se define dentro de otra función, permitiendo el acceso a las a las variables de las función externa. El hecho de retornar una función anidada permite mantener el acceso a las variables locales, argumentos y declaraciones de funciones internas de la función externa.Esta encapsulación nos permite
ocultar
y preservar el contexto de ejecución de ámbitos externos, al mismo tiempoexpone
una interfaz pública que pueda ser compartida y reutilizada en el futuro.Uno de los tipos más populares de
closures
es el famosopatrón de módulo
; el cual permite emular miembros públicos, privados y privilegiados:El patrón de módulo encapsula "privacidad", estado y organización utilizando
cierres/closures
. Proporciona una manera de envolver y mezclar variables y métodos públicos y privados también.Interfaz
Proteje a ciertas piezas de filtrarse en el ámbito global y de chocar accidentalmente con alguna otra interfaz. Con el patrón de módulo, solamente se devuelve una API pública, manteniendo todo lo demás dentro del
closure
privado.Reutilización
Como vimos, el
patrón de módulo
expone una interfaz que otras partes de nuestra aplicación pueden utilizar. Este patrón es muy similar a una expresión funcional inmediatamente-invocada (IIFE), excepto que en nuestro devolvemos un objeto en lugar de una función.¿Que permite () al final de la función?
El módulo actúa como si fuera un
singleton
, corre tan pronto como el compilador lo interpreta, por eso, la apertura y cierre de paréntesis al final de la función. Los únicos miembros disponibles fuera del contexto de ejecución delclosure
son sus métodos y propiedades ubicadas en el objeto público que se retorna. Sin embargo, todas las propiedades y métodos privados vivirán toda la vida de la aplicación mientras el contexto de ejecución se preserve, esto signifca que las variables pueden llegar a ser objeto de interacción via los métodos públicos.IIFE - Expresión de Función Inmediatamente-Autoinvocada
Otro tipo de
closure
es IIFE, que no es más que una función anónima auto-invocado que corre en el contexto dewindow
:Este tipo de expresión es útil cuando se trata de preservar el espacio de nombres global así como las variables declaradas dentro del cuerpo de la función serán locales al
closure
y viviran a lo largo de todo su tiempo de ejecución. Este es un tipo bastante popular de encapsulado de código fuente que usan mucho las aplicaciones y losframeworks
también, por lo general se usa para exponer una sola interfaz global con la cual se pueda interactuar.