¿Las declaraciones permiten crear propiedades en el objeto global?
En JavaScript, var
las declaraciones 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 alcance léxico con let
declaraciones 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
¿Las declaraciones crean
let
propiedades en el objeto global?
Según las especificaciones , no:
Un registro de entorno global es lógicamente un registro único, pero se especifica como un registro 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
GetThisBinding
método concreto del registro del 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 el 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 controlar 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 vinculante y viceversa. El entorno global tiene un objeto de entorno cuyo "objeto vinculante" es el objeto global. Otro ejemplo es
with
.
Ahora, como indica 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, sólo 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.
Guiones estándar:
Se puede acceder a ambas variables let
y var
, si se declaran en el nivel superior de un script, fuera del archivo del script. Sin embargo, sólo var
se asignan variables al window
objeto. 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>
Módulos Javascipt:
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>