En JavaScript, las declaraciones var crean propiedades en el objeto global:
var x = 15; console.log(window.x); // logs 15 in browser console.log(global.x); // logs 15 in Node.js ES6 introduce el alcance léxico con declaraciones let que tienen alcance de bloque.
let x = 15; { let x = 14; } console.log(x); // logs 15;Sin embargo, ¿estas declaraciones crean propiedades en el objeto global?
let x = 15; // what is this supposed to log in the browser according to ES6? console.log(window.x); // 15 in Firefox console.log(global.x); // undefined in Node.js with flag¿
letlas declaraciones creen propiedades en el objeto global?
De acuerdo con la especificación , no:
Un registro de entorno global es lógicamente un único registro, pero se especifica como un compuesto que encapsula un registro de entorno de objeto y un registro de entorno declarativo . El registro de entorno de objeto tiene como objeto base el objeto global del Reino asociado. Este objeto global es el valor devuelto por el método concreto
GetThisBindingdel registro de entorno global. El componente de registro de entorno de objeto de un registro de entorno global contiene los enlaces para todos los globales incorporados ( cláusula 18 ) y todos los enlaces introducidos por una FunctionDeclaration , GeneratorDeclaration o VariableStatement contenida en el código global. Los enlaces para todas las demás declaraciones de ECMAScript en código global están contenidos en el componente de registro de entorno declarativo del registro de entorno global.
Alguna explicación más:
Un registro de entorno declarativo almacena los enlaces en una estructura de datos interna. Es imposible obtener esa estructura de datos de ninguna manera (piense en el alcance de la función).
Un registro de entorno de objeto utiliza un objeto JS real como estructura de datos. Cada propiedad del objeto se convierte en un vínculo y viceversa. El entorno global tiene un objeto de entorno de objetos cuyo "objeto vinculante" es el objeto global. Otro ejemplo es with .
Ahora, como dice la parte citada, solo FunctionDeclaration s, GeneratorDeclaration s y VariableStatement s crean enlaces en el registro de entorno de objetos del entorno global. Es decir, solo estos enlaces se convierten en propiedades del objeto global.
Todas las demás declaraciones (por ejemplo, const y let ) se almacenan en el registro de entorno declarativo del entorno global, que no se basa en el objeto global.
Tanto las variables let como var , si se declaran en el nivel superior de una secuencia de comandos, son accesibles fuera del archivo de secuencia de comandos. Sin embargo, solo las variables var se asignan al objeto de window . Eche un vistazo a este fragmento de código como prueba:
<script> var namedWithVar = "with var"; let namedWithLet = "with let"; </script> <script> console.log("Accessed directly:"); console.log(namedWithVar); // prints: with var console.log(namedWithLet); // prints: with let console.log(""); console.log("Accessed through window:"); console.log(window.namedWithVar); // prints: with var console.log(window.namedWithLet); // prints: undefined </script>Tenga en cuenta que los módulos son una historia diferente. Las variables declaradas en un módulo no están disponibles en el ámbito global:
<script type="module"> var namedWithVar = "with var"; let namedWithLet = "with let"; </script> <script> console.log(namedWithVar); // ReferenceError </script> <script> console.log(namedWithLet); // ReferenceError </script> <script> console.log(window.namedWithVar); // prints: undefined console.log(window.namedWithLet); // prints: undefined </script>"Las declaraciones let y const definen variables que están en el ámbito del LexicalEnvironment del contexto de ejecución en ejecución".
Esto significa que debería poder acceder a la variable dentro del ámbito de ejecución, pero no fuera. Esto amplía el ámbito de ejecución más allá de la clásica estructura de cierre de JS de solo función o global.
Definir una variable let globalmente no debería exponer la variable en el contexto global, como solía ser el caso en Firefox. En la práctica, no debe definir variables en un contexto global.