salio - ¿Sobre qué parte de su alcance envolvente cierra un cierre(javascript)?
como cambiar un cierre (2)
Cuando tengo alguna función que utiliza variables de su (s) ámbito (s) adjunto (s) y la uso fuera de este ámbito (estos ámbitos), esto se denomina cierre.
¿Hay alguna especificación sobre el "cuánto" de su (s) ámbito (s) adjunto (s) que una función tiene que cerrar? (O, dicho de otra manera, sobre "cuánto menos" tiene que cerrarse absolutamente)
Considerar:
function Outer() {
var bigGuy = createSomethingHuge();
var tinyNumber = 42;
return (function () { /* CONTENTS */ });
}
O incluso:
function Layer1() {
var bigOne = somethingHugePlease();
var Layer2 = function() {
var bigToo = morePlease();
var Layer3 = function() {
var huge = reallyHuge();
var tiny = 42;
return (function () { /* CONTENTS */ });
};
return Layer3();
};
return Layer2();
}
¿Cuál de estas variables cierra la función final? ¿Depende de los contenidos de esa función final ( eval
...?)?
Me interesa sobre todo si existe algún tipo de especificación para estos casos, no tanto sobre el comportamiento de alguna implementación específica.
La cadena de alcance de una función anidada contiene referencias a objetos de activación de todas las funciones externas cuya ejecución dio como resultado la definición de la función anidada. Estos objetos de activación almacenan TODOS los valores en su lugar cuando se devolvió la llamada de función externa y continúan existiendo porque están en una cadena de alcance.
Entonces, un cierre, por definición, captura TODOS los valores variables en el alcance. eval("typeof bigGuy");
dentro de ''function () {/ * CONTENTS * /} debería demostrar esto.
Los estándares de ECMA probablemente * cubren esto (si está escribiendo un motor de JavaScript y tiene el tiempo). Una solución puede ser establecer variables de gran tamaño undefined
cuando su valor ya no sea necesario.
Me interesa sobre todo si hay algún tipo de especificación para estos casos
La especificación ECMAScript realmente no detalla esto. Simplemente dice que una función se cierra en todo el entorno léxico que incluye todas las variables en todos los ámbitos principales, organizados en los denominados registros de entorno.
Sin embargo, no especifica cómo una implementación debería hacer la recolección de basura, por lo que los motores sí tienen que optimizar sus cierres, y generalmente lo hacen, cuando pueden deducir que alguna variable "cerrada" nunca se necesita (referencia). Específicamente, si usa eval
en cualquier parte del cierre, no pueden hacer eso por supuesto, y tienen que retener todo.
no tanto sobre el comportamiento de alguna implementación específica
De todos modos, querrá echar un vistazo a Cómo se recogen los cierres de JavaScript , recolección de basura con node.js , Acerca del cierre, LexicalEnvironment y GC y Cómo se representan los cierres y ámbitos en tiempo de ejecución en JavaScript