/* Hoisting exampe - let */
let a = 100;
{
console.log(a); // 100
}
{
console.log(a); // ReferenceError: a is not defined
let a = 50;
}
/* Hoisting took place in {}. */
{
let a=100;
console.log(a); // 100
}
console.log(a); // ReferenceError: a is not defined
首先,我知道let和const有一个块作用域。
编译在执行上下文单元中进行,提升在创建LexicalEnvironment时发生。
执行上下文是通过执行全局、函数、eval代码创建的。
const和let的提升不应该在全局、函数、eval代码单元中完成吗?
(看起来吊装似乎没有发生,但这完全归功于TDZ的帮助。在内部,既可以提升也可以让提升。)
如果引擎在创建执行上下文时遇到块(而不是函数),那么引擎是否为块添加了一个新的作用域到[[Scope]]
发布于 2020-01-20 06:16:14
当一个块是第一次 (与{一起)时,一个新的执行上下文被创建,它创建一个新的空的词汇环境(它基本上是一个容器,将当前直接作用域中的变量名映射到它们的值)。然后,引擎反复遍历 --立即块中用const或let声明的所有变量--都被初始化。(但是,尽管已经初始化,但在引擎真正穿过const <variableName>或let <variableName>线( TDZ)之前,它们是不可引用的。)
因此,普通块确实创建了一个新的作用域,如果该块中的任何语句使用const或let声明变量,该作用域将被填充。
您可以在调试器中看到这一点:
/* Hoisting took place in {}. */
{
debugger;
let a=100;
console.log(a); // 100
}
console.log(a); // ReferenceError: a is not defined
Chrome devtools的结果:

(不过,这有点误导-- a实际上并不包含undefined,它还没有被完全创建)
const和let变量名被悬挂,因为解释器从块的一开始就识别引用它们是非法的,直到它们通过const或let行完全创建为止。
它不仅仅是简单的块--任何级别的代码都会导致同样的事情发生(比如在顶层,或者在for块中,或者在函数内部)。
https://stackoverflow.com/questions/59817679
复制相似问题