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

A javascript 'let' global variable is not a property of 'window' unlike a global 'var'

我曾经检查过全局 var 是否定义为:

if (window['myvar']==null) ...

if (window.myvar==null) ...

适用于 var myvar

现在我正在尝试切换到 let,这不再有效了。

var myvar='a';
console.log(window.myvar); // gives me a
let mylet='b';
console.log(window.mylet); // gives me undefined

问题: 使用全局 let,是否有任何地方可以查看是否已定义某些内容,就像我可以使用 window 对象中的 var 一样?

更普遍:
var myvar='a' 等同于 window.myvar='a' 吗?
我听到有人说在全球范围内,letvar are/behave 是一样的,但这不是我所看到的。

I hear people say that at the global level, let and var are/behave the same, but this is not what I am seeing.

嗯,是也不是。要回答您的问题,在大多数情况下 letvar 在全局声明时是相同的,但存在一些差异。

解释一下:全局环境记录是JS保存代码运行的所有逻辑和内存值的地方。然而,这个全局环境记录实际上是一个复合封装了一个对象环境记录和一个声明性环境记录.

更多解释:

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

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

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

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

TL;DR: 两者仍然是全局的,但是 vars 存储在 window 对象中,而 lets 存储在声明环境中你看不到的(就像你不能从函数外部访问函数范围内的变量一样)。当全局声明时,这两个语句在使用上几乎相同。