与全局'var'不同,javascript'let'全局变量不是'window'的属性

Fai*_* Ng 10 javascript var let

我过去常常检查是否var定义了全局:

if (window['myvar']==null) ...
Run Code Online (Sandbox Code Playgroud)

要么

if (window.myvar==null) ...
Run Code Online (Sandbox Code Playgroud)

它适用于 var myvar

现在我正在尝试切换到let,这不再起作用了.

var myvar='a';
console.log(window.myvar); // gives me a
let mylet='b';
console.log(window.mylet); // gives me undefined
Run Code Online (Sandbox Code Playgroud)

问题:一个全球性的let,没有任何的地方,如果有什么东西被像我可以定义我可以看看varwindow对象?

更普遍的:
var myvar='a'相当于window.myvar='a'
我听到人们说在全球范围内,let并且var/表现相同,但这不是我所看到的.

joh*_*667 20

我听到人们说在全球范围内,让和var的行为相同,但这不是我所看到的.

呃,是的,不是.要回答你的问题,在绝大多数情况下let,var在全球宣布时都是一样的,但也存在一些差异.

解释:全局环境记录是JS保留代码的所有逻辑和内存值的地方.但是,此全局环境记录实际上是一个封装对象环境记录声明性环境记录的组合.

更多解释:

声明环境记录存储在内部数据结构中的绑定.不可能以任何方式掌握该数据结构(考虑功能范围).

一个对象环境记录使用的实际JS对象作为数据结构.对象的每个属性都成为绑定,反之亦然.全局环境具有对象环境记录,其"绑定对象"是全局对象.这将是领域,在大多数情况下是window对象.

因此,根据ECMA规范,只有FunctionDeclarations,GeneratorDeclarationsVariableStatements全局环境的对象环境记录中创建绑定.

所有其他声明(即constlet)都存储在全局环境的声明性环境记录中,该记录不基于全局对象.它们仍然声明一个变量,但不是VariableStatement.

TL; DR:两者仍然是全局的,但是vars存储在window对象中,而lets存储在您无法看到的声明性环境中(就像您无法从函数外部访问函数作用域中的变量一样) ).当全局声明时,两个语句在使用时几乎完全相同.

  • 一个好的代码示例将非常适合此答案。 (3认同)
  • 这是使用 const 和 let 的最愚蠢、最随机、意想不到的副作用...... (2认同)