¿Es cierto que cada función en JavaScript es un cierre?
Entiendo que cada función en JavaScript es un objeto de primera clase y tiene una propiedad interna [[alcance]] que aloja los registros vinculantes de las variables libres de la función. Sin embargo, hay dos casos especiales.
¿La función creada por el constructor de funciones también es un cierre? El objeto de función creado por el constructor de funciones es especial, porque su [[alcance]] puede no referirse a los entornos léxicos de sus funciones externas, sino solo al contexto global. Por ejemplo,
var a = 1; var fn = (function outer() { var a = 2; var inner = new Function('alert(a); '); return inner; })(); fn(); // will alert 1, not 2.
Esto no es intuitivo. ¿A esto también se le llama cierre?
Si una función interna no tiene variables libres, ¿podemos decir que se forma un cierre cuando se crea la función interna? Por ejemplo,
// This is a useless case only for academic study var fn = (function outer() { var localVar1 = 1, localVar2 = 2; return function() {}; })();
En este caso, fn se refiere a un objeto de función vacío que se creó como una función interna. No tiene variables libres. ¿En este caso podemos decir que se forma un cierre?
¿La función creada por el constructor de funciones también es un cierre?
Sí, cierra el alcance global. Esto puede resultar poco intuitivo porque todos los demás cierres de JavaScript cierran su alcance léxico, pero aún así coincide con nuestra definición de cierre . En su ejemplo, a
es una variable libre y se resuelve en a
otro ámbito cuando se llama a la función inner
/ fn
en algún lugar.
Si una función interna no tiene variables libres, ¿aún podemos llamarla cierre?
Depende de a quién le preguntes. Algunos dicen que Sí, otros los llaman "cierres poco interesantes", personalmente digo No porque no hacen referencia a un ámbito externo.
Nota: Las funciones creadas con el constructor de funciones no crean cierres para sus contextos de creación; siempre se crean en el ámbito global. Al ejecutarlos, sólo podrán acceder a sus propias variables locales y globales, no a las del ámbito en el que se llamó al constructor de la Función. Esto es diferente de usar eval con código para una expresión de función.
de https://developer.mozilla.org