una salio que lubricar duro deslizador cremallera como cierre chaqueta cambiar baja arreglar anclaje javascript garbage-collection closures

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.

* Basado en leer ECMA 3.61 hace diez años. El término "cierre" de la informática no apareció en el estándar. La producción de cierres tiene que ser deducida por el lector como una consecuencia implícita de cómo se construyen las cadenas de alcance de funciones anidadas, que está en el estándar. Las cadenas de alcance comprenden el objeto de activación de la función que se está ejecutando actualmente, los objetos de activación de las funciones externas en orden inverso, seguidos por el objeto global. La cadena de alcance no se puede modificar en el código de usuario.

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