2012-08-20 22 views
6

Queriendo aclarar algo aquí ... así que tengo 2 preguntas¿Se considera que estos cierres son Javascript?

La siguiente función crea un cierre.

function Foo(message){ 
    var msg = message; 

    return function Bar(){ 
     this.talk = function(){alert(msg); } 
    } 
}; 

Q: ¿Cuál es la función del cierre, Foo o Bar?
Siempre pensé que el cierre era Foo, porque cerró-sobre Bar una vez que se devolvió Bar.

Siguiente ...

A continuación se muestra la definición de una función anónima:

()(); 

Q: Es el centro de la función dentro de esta función anónima también un cierre?

(function(){ /* <-- Is this function also a closure? */ })(); 
+0

No necesita esas etiquetas '
' en su pregunta. Además, '()();' no es una definición de una función anónima. – Pointy

+0

@Pointy Gracias, siempre me dijeron()(); es una función anónima Si no, ¿cómo se llama? –

+1

'()();' no tiene un nombre especial. El primer '()' es el operador de agrupamiento que obliga al contenido a tratarse como una expresión. Esto se usa para forzar que la definición de la función sea una expresión y no se trate como una declaración. El segundo '()' llama a la función en este caso, pero sería un error si el resultado de evaluar el operador de agrupación no es una función. Una función anónima es simplemente una función sin nombre. –

Respuesta

4

Debe utilizar los primeros principios aquí. Javascript usa alcance léxico. Esto significa que el alcance de un contexto de ejecución está determinado por la forma en que el código es definido como (léxico).

, diría que la definición de la función Bar es lo que hace que el cierre que se cree, debido a msg es "cerrada-in" en la función.

La creación real del cierre ocurre en tiempo de ejecución (que es algo así como una declaración tautológica, ya que nada en un programa informático que pasa hasta que se ejecuta), porque a fin de determinar el valor de msg, en Bar, cuando Bar se ejecuta, el intérprete necesita saber el valor de la variable cuando se ejecuta Foo, y así sucesivamente hasta la cadena.

Voy a dar dos respuestas a su pregunta. La respuesta pedante es: ninguna de las dos funciones es el cierre. Es la definición de las variables dentro de las funciones, combinadas con el contexto de ejecución de las funciones cuando se ejecutan, es decir, define el cierre. La respuesta común es: cualquier función que cierre una variable es un cierre (Bar en su caso).

Considere el problema que todos encuentran al usar Javascript.

function A(x) { 
    var y = x, fs = []; 

    for (var i = 0; i < 3; i++) { 
     fs.push(function(){ 
     console.log (i + " " + x); 
     }) 
    } 

    fs.forEach(function(g){g()}) 
} 

A('hi') 

La mayoría de la gente diría que esto produciría la salida 'hola 1' seguido de 'hi 2' seguido de 'hi 3'. Sin embargo, produce 'hi 3' 3 veces. Si solo la definición de la función que se agrega a la matriz, al usar variables definidas en la función externa, creó el cierre, ¿cómo puede ser esto?

Es porque necesita el contexto de ejecución para definir el cierre, lo que no sucede hasta el tiempo de ejecución. En la ejecución de las funciones en la matriz, i tiene el valor 3. En la declaración forEach, ese es el contexto de ejecución, por lo que la salida siempre usa 3.

+0

Quieres decir "... cuando Foo es exculpado". Creo. – Pointy

+1

¿Qué quieres decir? La existencia de 'Bar' y su uso de' msg' es lo que causa el cierre. – hvgotcodes

1

Bar es el cierre.

Decimos que Barcierra la variable msg en su entorno.

Lo más frecuente es que la palabra cierre signifique: una función que utiliza al menos una variable definida en un ámbito delimitador, en una función envolvente.

Para responder a su segunda pregunta: (function(){ ... })() es exactamente lo que parece: una función anónima, no dos. A menos que esté anidado dentro de otra función, generalmente no lo llamará cierre. Sin embargo, las funciones anidadas dentro de esa función anónima pueden ser cierres (y a menudo lo son).

+0

+1 por la respuesta directa ... Desearía poder votar, por dos respuestas. –

Cuestiones relacionadas