Académique Documents
Professionnel Documents
Culture Documents
http://www.variablenotfound.com/2012/10/closures-en-javascript-entiendelos-de.html
Concepto de closure
Cuando nos acercamos por primera vez al concepto de closure es habitual
encontrarnos con problemas a la hora de entenderlo, a pesar de que seguramente en
muchas ocasiones los habremos utilizado sin saberlo. Por este motivo, antes de
intentar dar una definicin ms o menos acadmica, creo que es mucho ms prctico
saber identificar los closures en el cdigo, que al fin y al cabo es el lenguaje natural del
programador.
En primer lugar podemos ver claramente que tenemos dos funciones, y que la
funcin greet() est definida dentro de la funcin personalizedGreet().
En segundo lugar podemos observar como la funcin greet() utiliza en su
cuerpo una variable local perteneciente al mbito de la funcin
personalizedGreet().
Siempre que se produzcan estos dos elementos podemos decir que tenemos un
closure entre manos. As de sencillo! Comprobemos ahora cmo funciona el cdigo
que hemos visto en la imagen anterior.
Comportamiento
Para terminar de captar el concepto veamos ahora una serie de comportamientos o
caractersticas que tienen los closures y que tendremos que tener siempre presentes
cuando trabajamos con esta potente herramienta del lenguaje JavaScript.
Cmo se crean los closures
Cuando el intrprete de JavaScript encuentra un closure guarda las variables locales
que las funciones internas van a necesitar. Esto ya lo hemos comentado, pero...
cmo acceden las funciones a estas variables? Veamos algunos apuntes sobre esto:
La idea principal es que el valor de la variable puede ser modificada a lo largo del
cdigo y que las funciones internas guardan una referencia a la memoria donde
se encuentra el ltimo valor de la variable que fue asignada al salir de la funcin
externa. Es importante tener esto presente y, como veremos ahora, tiene algunos
comportamientos que en principio podran sorprender.
Definir o modificar la variable despus de la funcin interna
En los ejemplos de cdigo que hemos comentado anteriormente la variable local de la
funcin externa se encontraba definida antes que la funcin anidada. Lo contrario es
perfectamente vlido.
En el siguiente ejemplo tenemos una funcin que define en su interior una constante
(con valor 10) que ser incrementada en una cantidad pasada como parmetro a la
funcin:
Pensad por un momento cual ser la salida en pantalla de este cdigo, 10 15. Los
que hayis respondido 15 estis en lo cierto. Los que no, es normal, se tiende a
pensar que el closure queda establecido en el comento que se define la funcin
anidada, pero no es as. Como ya hemos comentado, la funcin interna
simplemente almacena una referencia al ltimo valor de la variable establecido
cuando la funcin externa termina de ejecutarse.
Cada llamada es un closure distinto
Visto lo anterior podra pensarse que el closure es un elemento global que persiste
entre llamadas. No es as, por cada llamada que hagamos a la funcin externa
estaremos creando un nuevo e individual closure. Veamos el ejemplo siguiente.
Piense el lector por un momento cul ser la salida de este script. Efectivamente, la
salida son tres mensajes seguidos con el texto "Toma ya!!". Notar que las tres
funciones internas mantienen una referencia al mismo valor, es decir, las tres
variables globales pertenecen al mismo closure. De hecho, este podra ser el caso
del esquema que hemos visto en la imagen cuando hablbamos de como se crean los
closures.
Pero compliquemos el cdigo un poco.
Aplicaciones prcticas
Ahora que seguramente que ya hemos entendido cmo se comportan los closures,
pasemos a algo ms prctico. En seguida vamos a ver algunos ejemplos donde
podemos comprobar en el campo de batalla la potencia de esta caracterstica del
lenguaje. Tenga el lector en cuenta que aplicaciones sobre este concepto pueden ser
tantas como las necesidades o imaginacin de los programadores, aqu veremos solo
algunas.
Ejecutar funciones retardadas
Quizs este sea el ejemplo prctico ms clsico y que el lector seguramente ya
conocer. En ocasiones en nuestro cdigo JavaScript podemos necesitar realizar
operaciones con retardo, para ello JavaScript nos provee de las funciones
setTimeout() y setInterval().
Referencias