我已经玩ES6一段时间了,我注意到虽然声明的变量var按预期提升了......
console.log(typeof name); // undefined
var name = "John";
Run Code Online (Sandbox Code Playgroud)
... 用吊装声明let或const似乎有一些问题的变量:
console.log(typeof name); // ReferenceError
let name = "John";
Run Code Online (Sandbox Code Playgroud)
和
console.log(typeof name); // ReferenceError
const name = "John";
Run Code Online (Sandbox Code Playgroud)
这是否意味着变量声明let或未声明const?这是怎么回事?这个问题let和const这个问题有什么区别吗?
我听说在初始化之前访问let和const值可能会导致ReferenceError因为称为时间死区的东西.
什么是暂时死区,它与范围和吊装有什么关系,以及在什么情况下遇到?
我正在阅读这本名为 Eloquent JavaScript 的好书,但我对这个例子中“绑定”这个词的使用感到困惑:
通过在属性名称周围使用方括号,可以在对象表达式和类中包含符号属性。这会导致属性名称被评估,就像方括号属性访问符号一样,它允许我们引用一个包含符号的绑定。
let stringObject = {
[toStringSymbol]() { return "a jute rope"; }
};
console.log(stringObject[toStringSymbol]());
// ? a jute rope
Run Code Online (Sandbox Code Playgroud)
据我了解(到目前为止在我的 JS 旅程中),“绑定”与指定this函数在哪个或对象上下文中运行有关。看这里。. 绑定可能与上下文有关。这就是为什么我们有.bind().
但是在这个例子中,我们绑定了其他东西(一个键是符号的方法)。是否binding只是意味着将属性(原语或方法)附加到对象上?
我一直试图弄清楚时间死区/解析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.变量在块的开始处于"临时死区",直到处理初始化为止.
术语“初始化”和“赋值”似乎可以互换使用。我做了一些搜索,似乎技术上可能存在差异。我的理解是,在变量的上下文中,当 JavaScript 引擎使其可供使用时,变量就会被初始化,而赋值(无论是显式完成 [如let foo = 1;] 还是由 JavaScript 引擎完成,如下例所示)是一种方法为了达成这个。
let foo;
console.log(foo); // undefined (initialization and assignment?)
Run Code Online (Sandbox Code Playgroud)
我的理解正确吗?另外(如果是这样),在初始化过程中实际发生了什么以使变量可用?