此代码可以正常工作:
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
没有悬挂,但是&#34;某些东西&#34; (一些元数据?)似乎仍然悬而未决,否则我们就没有问题了。
答案 0 :(得分:2)
吊装是指变量声明被提升到变量范围顶部的概念。
更准确地说,JavaScript的两个过程中构建它的执行环境是一个副作用。
第一遍设置所有函数和变量声明。在此阶段,声明变量但未定义变量,声明和定义函数声明(即函数声明:function fnName(){...}
不 变量函数表达式:var fnName = function (){...}
)。
第二遍然后使用可用的声明函数和变量(当前未分配,因此具有未定义的值)执行代码。
var
function 作用域,而不是块作用域。
虽然let
和const
允许声明块作用域变量,但代码是使用两个执行过程构建的。区别在于块范围应该在它们自己的范围内的第一遍中被考虑(块范围或其他)。
为了说明这一点,请考虑您的第二个片段。
代码在第二种情况下抛出错误,因为在第一次传递后它可以重写为:
// 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;
}
答案 1 :(得分:1)
根据ES6规范,使用let
和const
进行变量声明。
它们都是 Block Scoped
范围内声明之前的时间是temporal dead zone。
根据文件:
在ECMAScript 2015中,让我们将变量提升到顶部 块。但是,在之前引用块中的变量 变量声明导致ReferenceError。变量在a中 &#34;时间死区&#34;从块的开始直到声明 处理完毕。
正如@Bergi所说,它是实际声明之前的时间。