【问题标题】:How does JS variable override work? [duplicate]JS 变量覆盖是如何工作的? [复制]
【发布时间】:2017-08-26 16:57:18
【问题描述】:

这段代码运行良好:

const a = 1;
{
  const b = a; // let's use "a" in a sub-scope
}
{
  const a = 2; // let's override "a" in another sub-scope
}

...但此代码在第 3 行以 a is not defined 失败:

const a = 1;
{
  const b = a; // let's use "a" in a sub-scope <<< CRASH!! >>>
  const a = 2; // let's override "a" in the same sub-scope
}

我在node 7.7.4 上对此进行了测试。它可能仅与 V8 有关,我很好奇 Firefox 将如何处理。

是否与JS规范中定义变量声明的方式有关? const/let 没有被提升,但“某物”(一些元数据?)似乎仍然被提升,否则我们不会有任何问题。

【问题讨论】:

  • 所有声明在 JavaScript 中被提升到其作用域的顶部。对于constlet,这是范围块。

标签: javascript ecmascript-6


【解决方案1】:

这是根据 ES6 规范使用 letconst 进行变量声明的。 它们都是块作用域
范围内声明前的时间为temporal dead zone。 根据文档:

在 ECMAScript 2015 中,让我们将变量提升到顶部 堵塞。但是,引用之前块中的变量 变量声明会导致 ReferenceError。变量在一个 从区块开始到声明的“时间死区” 已处理。

正如@Bergi 所说,这是实际声明之前的时间

【讨论】:

  • 谢谢!事实上,我偶然发现了同一篇文章,我很高兴它很好地描述了 TDZ。我有点难过,因为我的例子在 Java、C++ 和其他主流语言中是合法的。我认为let/const 会让 JS 在语法上更接近它们。很高兴知道想法。
  • 它被称为temporal死区,因为它不是一个“区域”而是一个时间段。 “之前”并不意味着空间。
【解决方案2】:

提升是指变量声明被提升到变量范围顶部的概念。

更准确地说,这是 JavaScript 分两次构建其执行环境这一事实的副作用。

第一遍设置所有函数和变量声明。在这个阶段,变量被声明但未定义,函数声明被声明和定义(即函数声明function fnName(){...}不是变量函数表达式:var fnName = function (){...})。

第二遍然后使用可用的已声明函数和变量(当前未分配,因此具有未定义的值)执行代码。

varfunction 作用域的,而不是 block 作用域。 尽管letconst 允许声明块范围的变量,但代码是使用两个执行通道构建的。不同之处在于块范围应在其自己的范围内(块范围或其他)的第一遍考虑。

为了说明这一点,请考虑您的第二个 sn-p。

代码在第二种情况下会引发错误,因为在第一次通过后它可能会被重写为:

// const 'a' declared in this outer scope
const a:
a = 1; 

{ 
  // separate const 'a' declared in this block scope
  // Declarations still hoisted for this block scope
  const b, a
  b = a; // a undefined here
  a = 2;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-05-14
    • 1970-01-01
    • 2018-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-12
    相关资源
    最近更新 更多