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.
No necesita esas etiquetas '
' en su pregunta. Además, '()();' no es una definición de una función anónima. – Pointy
@Pointy Gracias, siempre me dijeron()(); es una función anónima Si no, ¿cómo se llama? –
'()();' 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. –