问题描述
在“您还不了解 JS ”的“第 5 章:变量的(并非如此)秘密生命周期”中,标题为 "Uninitialized Variables (aka,TDZ)" 的部分表示初始化未初始化的 {{1} } 变量带有附加到声明语句的赋值(因为赋值本身是不够的)。以下示例说明了这一点。
示例 1:
let
在下一个示例中,声明和初始化是分开的 - let studentName = "Suzy";
console.log(studentName); // Suzy
变量在第 1 行声明,然后在第 2 行初始化:
示例 2:
let
这很有趣!回想一下之前,我们说过 let studentName;
// or:
// let studentName = undefined;
studentName = "Suzy";
console.log(studentName);
// Suzy
与 var studentName;
不同,但这里有 var studentName = undefined;
,
他们的行为相同。差异归结为 var
studentName 在作用域的顶部自动初始化,其中
让 studentName 没有。
问题 1:
我不确定上面的示例 2 如何证明 let
和 let studentName;
是等效的。在本章前面,标题为 "Redeclaration?" 的部分使用以下示例来说明 let studentName = undefined;
与 var studentName;
不同:
示例 3:
var studentName = undefined;
在上面的例子中,第二个 var studentName = "Frank";
console.log(studentName); // Frank
var studentName;
console.log(studentName); // Frank <--- still!
// let's add the initialization explicitly
var studentName = undefined;
console.log(studentName); // undefined <--- see!?
声明基本上是一个空操作,因为 studentName
已经被声明了。但这与 studentName
示例(示例 2)有何关系?即示例 2 如何表明 let
和 let studentName;
的行为相同?
问题 2:
上面标注的第二句说,“区别在于 let studentName = undefined;
在作用域的顶部自动初始化,而 var studentName
没有。”但是如果在声明时没有指定值,let studentName
不会自动初始化为 let
(参见 here)?
编辑:
我的不好 - 关于问题 2,标注的第二句话确实有道理。 specs 表示如果 undefined
声明没有初始化表达式,那么当 let
声明是 评估。而如果 let
声明是在没有初始化程序的情况下进行的,那么该 var 声明的变量将在 创建({{ 3}}).
但是,我仍然不确定问题 1。
解决方法
重要区别之一:
区别在于 var studentName 在作用域的顶部自动初始化,而 let studentName 没有。
未在您的问题中的示例片段中说明,因为您不会在声明之前尝试访问用 let
声明的变量。
在上面的例子中,第二个 studentName 声明基本上是一个空操作,因为已经声明了 studentName。但这与 let 示例有何关系?
使用 let
,不允许重新声明 - 相反,代码中必须有一个 single 语句,在那里可以确定变量名是暂时死的zone 并被代码的其他部分引用。直到一个变量被完全初始化——也就是说,直到解释器运行过 let someVarName
行(无论是否用 =
分配给它)——变量名不能分配给或检索。
除此之外,let someVarName
与 var someVarName
非常相似 - let
会在那个时刻为变量赋值 undefined
,而 {{1} } 将在作用域的开头为变量赋予 var
值。
“差异归结为 var studentName 在作用域的顶部自动初始化,而 let studentName 没有。”我不确定这是什么意思,因为我一直认为如果在声明时没有指定值,let 会自动初始化为 undefined
查看示例:
undefined
比较:
// Not permitted:
console.log(studentName); // Error
let studentName;
使用 // OK
console.log(studentName);
var studentName;
,在解释器运行过 let
行之前,您不能引用所述变量。