我听说在初始化之前访问let
和const
值可能会导致ReferenceError
因为称为时间死区的东西.
什么是暂时死区,它与范围和吊装有什么关系,以及在什么情况下遇到?
我一直试图弄清楚时间死区/解析let
和const
工作方式.这就是它似乎归结为(基于我在以前的问题中收到的文档和各种回答[例如这个和这个 ],尽管这与一些答案存在分歧).这个摘要是正确的吗?
在作用域的顶部,JS引擎let foo;
在相关作用域的顶部创建一个绑定(变量关键字和名称的关联,例如),这被认为是提升变量,但如果您尝试之前访问该变量它的声明的位置,JS抛出一个ReferenceError
.
一旦JS引擎向下移动到声明(与"定义"同义),例如,let foo;
引擎就会初始化它(为它分配内存并使其可访问).声明具有自我约束力.(这是对我来说没有意义的部分:绑定导致顶部的提升,但引擎不会初始化,直到它到达声明,这也有绑定效果.)如果没有赋值,变量的值设置为or undefined
的情况let
,如果const
使用,SyntaxError
则抛出a.
这里是参考规格说的:
ECMAScript 2019语言规范草案:第13.3.1节,Let和Const声明
let和const声明定义了作用于正在运行的执行上下文的LexicalEnvironment的变量.变量是在实例化包含词法环境时创建的,但在评估变量的LexicalBinding之前可能无法以任何方式访问它们.当LexicalBinding被评估时,由LexicalBinding和Initializer定义的变量被赋予其Initializer的AssignmentExpression的值,而不是在创建变量时.如果let声明中的LexicalBinding没有Initializer,则在评估LexicalBinding时,会为变量赋值undefined.
MDN Web Docs:让我们
让绑定在包含声明的(块)范围的顶部创建,通常称为"提升".与使用var声明的变量(将以未定义的值开头)不同,在定义其定义之前,不会初始化变量.在初始化之前访问变量会导致ReferenceError.变量在块的开始处于"临时死区",直到处理初始化为止.