首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >主持let,const

主持let,const
EN

Stack Overflow用户
提问于 2020-01-20 05:56:10
回答 1查看 562关注 0票数 0

代码语言:javascript
复制
/* Hoisting exampe - let */
let a = 100;
{
	console.log(a); // 100
}
{
	console.log(a); // ReferenceError: a is not defined
	let a = 50;
}

代码语言:javascript
复制
/* Hoisting took place in {}. */
{
	let a=100;
	console.log(a); // 100
}
console.log(a); // ReferenceError: a is not defined

首先,我知道letconst有一个块作用域

编译在执行上下文单元中进行,提升在创建LexicalEnvironment时发生。

执行上下文是通过执行全局函数eval代码创建的。

constlet的提升不应该在全局函数eval代码单元中完成吗?

(看起来吊装似乎没有发生,但这完全归功于TDZ的帮助。在内部,既可以提升也可以让提升。)

如果引擎在创建执行上下文时遇到块(而不是函数),那么引擎是否为块添加了一个新的作用域到[[Scope]]

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-01-20 06:16:14

当一个块是第一次 (与{一起)时,一个新的执行上下文被创建,它创建一个新的空的词汇环境(它基本上是一个容器,将当前直接作用域中的变量名映射到它们的值)。然后,引擎反复遍历 --立即块中用constlet声明的所有变量--都被初始化。(但是,尽管已经初始化,但在引擎真正穿过const <variableName>let <variableName>线( TDZ)之前,它们是不可引用的。)

因此,普通块确实创建了一个新的作用域,如果该块中的任何语句使用constlet声明变量,该作用域将被填充。

您可以在调试器中看到这一点:

代码语言:javascript
复制
/* Hoisting took place in {}. */
{
    debugger;
    let a=100;
    console.log(a); // 100
}
console.log(a); // ReferenceError: a is not defined

Chrome devtools的结果:

(不过,这有点误导-- a实际上并不包含undefined,它还没有被完全创建)

constlet变量名被悬挂,因为解释器从块的一开始就识别引用它们是非法的,直到它们通过constlet行完全创建为止。

它不仅仅是简单的块--任何级别的代码都会导致同样的事情发生(比如在顶层,或者在for块中,或者在函数内部)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59817679

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档