javascript - 托管 let, const
问题描述
/* 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
创建时。
执行上下文是由global , function , eval代码的执行创建的。
不应该在global , function , eval代码单元中提升const
和完成吗?
(似乎提升似乎没有发生,但这完全归功于 TDZ 的帮助。内部 const 和 let 提升。)let
如果引擎在创建执行上下文时遇到块{/* code */}
(而不是函数),引擎是否会为块添加新范围?[[Scope]]
解决方案
当第一次遇到块时(使用),会创建{
一个新的执行上下文,这会创建一个新的空词法环境(它基本上是一个容器,将当前直接作用域中的变量名映射到它们的值)。然后引擎遍历所有用立即块声明或在立即块中初始化的变量。(但是,尽管已初始化,但在引擎真正遇到or线 - TDZ 之前,它们是不可引用的)const
let
const <variableName>
let <variableName>
因此,普通块确实创建了一个新范围,如果该块内的任何语句使用const
or声明变量,则该范围将被填充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
orlet
行完全创建。
它不仅仅是简单的块 -任何级别的代码都会导致发生相同类型的事情(例如在顶层,或在for
块内,或在函数内)。
推荐阅读
- powershell - AD中的用户创建
- swift - 可选属性导致 Swift 协议崩溃
- python - 正则表达式中的 Python 可选组
- python - Python selenium - 我如何能够点击屏幕上具有特定值的所有按钮
- sql - JOIN 条件下的 SQL 查询
- python - Python numpy:用特定范围内的新值替换值的for循环向量
- flutter - 我已删除 Pub\Cache\hosted\pub.dartlang.org 文件夹以更新颤振包,但在颤振包中显示错误获取
- python - 集成终端停止在 Visual Studio Code 中显示文本
- python-3.x - 即使安装 ffmpeg 也找不到 FFserver 命令
- javascript - 如何从 Map.keys() 中获取排序数组