外部作用域中定义的变量未在内部作用域中定义



以下代码抛出一个 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 上清楚地描述的那样,这不是它的工作方式。

但是为什么它会以这种方式工作?为什么球拍同时有让和让*形式?

这是

由于将内部letconst提升到块(MDN)的顶部,并创建一个临时死区

在 ECMAScript 2015 中,let 将变量提升到 块。但是,在块中引用变量之前 变量声明会导致引用错误。变量位于 从块开始到声明的"时间死区" 正在处理。

这背后的原因很简单 - 静默失败与抛出错误。

在此示例中,由于var提升,类似的设置将结果显示为undefined。这是一个静默错误,可能很难调试。

{
    var a = 'a1';
    (function() {
        console.log(a);
        var a = 'a2';
    })();
}

如果要使用 letconst将引发错误:

{
  let a = 'a1';
  (function() {
    console.log(a);
    let a = 'a2';
  })();
}

您可以在文章时间

盲区 (TDZ) 揭秘中找到有关时间盲区的更多信息。

最新更新