让语句在全局对象上创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章 )的绑定以及由全局代码中包含的FunctionDeclarationGeneratorDeclarationVariableStatement引入的所有绑定。 全局代码中所有其他ECMAScript声明的绑定都包含在全局环境logging的声明性环境logging组件中。

更多的解释:

  • 声明性环境logging将绑定存储在内部数据结构中。 以任何方式获得该数据结构是不可能的(思考函数范围)。

  • 对象环境logging使用实际的JS对象作为数据结构。 对象的每个属性都成为绑定,反之亦然。 全局环境有一个“绑定对象”是全局对象的对象环境对象。 另一个例子是with

现在,如引用的部分所述,只有FunctionDeclarationGeneratorDeclarationVariableStatement在全局环境的对象环境logging中创build绑定。 即只有这个绑定成为全局对象的属性。

所有其他声明(如constlet )都存储在全局环境的声明性环境logging中,而不是基于全局对象。

根据规范 :

“let和const声明定义了作用域正在运行的执行上下文的LexicalEnvironment的variables。”

这意味着你应该能够访问执行范围内的variables,但不能在外面访问。 这扩大了执行范围,超越了经典的仅限于函数或全局的JS闭包结构。

在全局定义一个letvariables的时候,可以将其解释为开放的,就像在Firefox中看到的那样,它绑定了一个全局variables,而V8 / iojs则不会。

值得一提的是console.log(typeof x)会在iojs中返回number 。 在实践中,你不应该定义模块以外的variables,或尽可能多的函数…尤其是constlet