2010-07-20 18 views
13

Am envolviendo mi cabeza alrededor de los cierres de JavaScript y estoy en un punto donde las cosas están cayendo en su lugar; es decir es un cierre de las variables locales de una función - mantenido con vida después de la función ha vuelto, o un cierre es un marco de pila que no se cancela la asignación cuando se devuelve la función.¿Por qué tenemos cierres en JavaScript?

Estoy empezando a entender este concepto, pero cuanto más entiendo, más me pregunto por qué tenemos que usarlos.

Un ejemplo como este me hace entender el concepto pero me deja preguntando, ¡hay una manera más simple de hacerlo!

function sayHello(name) { 
    var text = 'Hello ' + name; 
    var sayAlert = function() { alert(text); } 
    sayAlert(); 
} 
sayHello('Gath'); 

Me pregunto por qué tengo que mantener viva la variable local? después de que la función ha salido?

¿Dónde puedo obtener ejemplos que muestran las soluciones implementadas por cierre y que nada más habría funcionado sino cierres?

+7

Busque aquí un gran lote de respuestas: http://stackoverflow.com/questions/111102/how-does-a-javascript-closure-work –

Respuesta

7

Los cierres se suman fuerza expresiva de la lengua. Hay algunos patrones que pueden implementarse muy fácilmente debido a los cierres. Unos pocos ejemplos que vienen a la mente son:

0

El ejemplo que elige aparece en this page, por lo que supongo que lo tomó de allí. ¿Has mirado todos los otros ejemplos que proporciona? Explican las motivaciones para los cierres mejor de lo que podría.

+0

Sí, lo hice, pero todavía no muestran un escenario donde todo lo demás falló y el cierre fue lo único que pudo hacer el truco – gath

+0

@gath - sí lo hacen. Muchos de esos ejemplos son funciones que tienen otras funciones como valor de retorno. Si llama a la función externa, guarda una referencia a la función devuelta y luego llama a la función devuelta en algún momento posterior, esos ejemplos no podrían funcionar sin cierres. –

+0

@gath: todo se puede escribir en ensamblador. Los cierres no se inventaron para resolver problemas que nunca podrían resolverse antes, por lo que no encontrarás ningún problema que solo pueda resolverse con cierres. Ellos hacen que ciertos problemas sean mucho más simples de resolver, y si revisas esos ejemplos con esto en mente, podrían comenzar a tener más sentido para ti. –

2

Un cierre es una función con todo el entorno necesario para que se ejecute. En javascript, es cuando se crea una función anónima (= lambda), utilizando una variable de un ámbito externo.

Se puede entender mejor por qué con un código de esa manera:

function foo() 
{ 
    var text = computeFromOutside(); 
    // ... other lines of code 
    return function(otherText) { return text + otherText; } 
} 

bar = foo(); 

function baz(fun) 
{ 
    return fun("some text"); 
} 

Aquí, están regresando una función que utiliza la variable local "texto". Por lo tanto, está dejando el alcance de la función foo, destruyendo sus variables. Sin embargo, dado que tenemos una función anónima que utiliza texto, debemos mantener un seguimiento de esta variable. Esto se puede lograr por valor o por referencia, en función del idioma (Mantener viva la variable (con la posibilidad de modificarlo después, o copiar su valor cuando se crea la función)).

espero que esto ayude!

0

una función normal hace su cosa, calcula un resultado y lo devuelve. Al devolver un cierre, puede empaquetar su trabajo a mitad de camino y permitir que las personas que llaman obtengan más cuando estén listas para ello. Desde que probé Scheme en la universidad, he estado anhelo de cierres en todos los idiomas que he trabajado desde ... son peligrosamente hábito!

También se podría decir que son una parte importante del futuro: junto con otros mecanismos de programación funcional que parecen adecuados para la programación paralela de sistemas multi-core.

2

"Un cierre es el objeto de un pobre. Un objeto es el cierre de un hombre pobre". (Lo siento, olvidé la fuente).

A veces necesitamos variables que solo son necesarias por un bloque de código. Colocamos ese bloque de código en una función y tenemos esas variables como variables locales para esa función.

A veces necesitamos las variables que son necesarias por todas las funciones/bloques de código en el programa. Podemos tener estas variables como variables globales.

A veces necesitamos variables que son necesarias por algunas funciones/bloques de código. Por ejemplo, tenemos una entidad llamada Ventas y queremos unir todos nuestros códigos relacionados con las ventas. Entonces tenemos un grupo de funciones y un grupo de variables que trata sobre las ventas. Podemos poner estas funciones y variables juntas en un objeto, de modo que estén aisladas (tanto las funciones como las variables) de otras partes del código.

En los idiomas que no admiten objetos directamente, podemos tener funciones anidadas. La función externa actúa como clase, las funciones internas actúan como métodos. Las variables locales a la función externa actúan como campos, solo son accesibles a las funciones internas. En llamadas posteriores a funciones internas, queremos mantener el estado de las variables de función local a externa, aquí es donde se necesitan cierres. Todo lo que tenemos que hacer es pasar referencia a cualquier función interna a través de la salida de la función externa, para codificar fuera de la función externa, de modo que las variables de la función externa accedidas por la función interna se conserven incluso después de que la función externa finalice.

+0

esta es una excelente analogía – qodeninja

Cuestiones relacionadas