让语句在全局对象上创build属性?
在JavaScript中, var
声明在全局对象上创build属性:
var x = 15; console.log(window.x); // logs 15 in browser console.log(global.x); // logs 15 in Node.js
ES6引入了具有块范围的声明的词法范围。
let x = 15; { let x = 14; } console.log(x); // logs 15;
但是,这些声明是否会在全局对象上创build属性?
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
let
语句在全局对象上创build属性?
根据规范 ,没有:
全局环境logging在逻辑上是单个logging,但是它被指定为封装对象环境logging和声明性环境logging的组合 。 对象环境logging具有关联的Realm的全局对象作为其基础对象。 这个全局对象是全局环境logging的
GetThisBinding
具体方法返回的值。 全局环境logging的对象环境logging组件包含所有内置全局variables( 第18章 )的绑定以及由全局代码中包含的FunctionDeclaration , GeneratorDeclaration或VariableStatement引入的所有绑定。 全局代码中所有其他ECMAScript声明的绑定都包含在全局环境logging的声明性环境logging组件中。
更多的解释:
-
声明性环境logging将绑定存储在内部数据结构中。 以任何方式获得该数据结构是不可能的(思考函数范围)。
-
对象环境logging使用实际的JS对象作为数据结构。 对象的每个属性都成为绑定,反之亦然。 全局环境有一个“绑定对象”是全局对象的对象环境对象。 另一个例子是
with
。
现在,如引用的部分所述,只有FunctionDeclaration , GeneratorDeclaration和VariableStatement在全局环境的对象环境logging中创build绑定。 即只有这个绑定成为全局对象的属性。
所有其他声明(如const
和let
)都存储在全局环境的声明性环境logging中,而不是基于全局对象。
根据规范 :
“let和const声明定义了作用域正在运行的执行上下文的LexicalEnvironment的variables。”
这意味着你应该能够访问执行范围内的variables,但不能在外面访问。 这扩大了执行范围,超越了经典的仅限于函数或全局的JS闭包结构。
在全局定义一个let
variables的时候,可以将其解释为开放的,就像在Firefox中看到的那样,它绑定了一个全局variables,而V8 / iojs则不会。
值得一提的是console.log(typeof x)
会在iojs中返回number
。 在实践中,你不应该定义模块以外的variables,或尽可能多的函数…尤其是const
和let