以下代码抛出一个 ReferenceError 'a is not defined'。
{
let a = 'a1';
{
console.log(a);
let a = 'a2';
}
}
下一个也是如此。
{
const a = 'a1';
{
console.log(a);
const a = 'a2';
}
}
如果您改用 var 声明,它会按照我的预期工作。(未引发错误错误并记录"a1"。
当我尝试分析以下代码时,我变得更加难以理解。
{
let a = 'a1';
{
console.log(a);
var a = 'a2';
}
}
它抛出一个语法错误,"标识符'a'已被声明"。
天真地,我期望标识符直到 let 或 const 声明之后才会被遮蔽,就像 Clojure 中的 let 或 Racket 中的 let* 一样。正如 MDN 上清楚地描述的那样,这不是它的工作方式。
但是为什么它会以这种方式工作?为什么球拍同时有让和让*形式?
由于将内部let
或const
提升到块(MDN)的顶部,并创建一个临时死区。
在 ECMAScript 2015 中,let 将变量提升到 块。但是,在块中引用变量之前 变量声明会导致引用错误。变量位于 从块开始到声明的"时间死区" 正在处理。
这背后的原因很简单 - 静默失败与抛出错误。
在此示例中,由于var
提升,类似的设置将结果显示为undefined
。这是一个静默错误,可能很难调试。
{
var a = 'a1';
(function() {
console.log(a);
var a = 'a2';
})();
}
如果要使用 let
或 const
将引发错误:
{
let a = 'a1';
(function() {
console.log(a);
let a = 'a2';
})();
}
您可以在文章时间盲区 (TDZ) 揭秘中找到有关时间盲区的更多信息。