首页 > 解决方案 > 即使在使用未定义的 var 类型的变量初始化后,在块范围内也会注销意外值

问题描述

function show() {
  var x = 10;
  if (true) {
    var x = 20;
  }
  console.log(x); // 20
}

show();

但是,当我没有手动初始化“if-statement”中的“x”时,它会使用undefined进行初始化并提升到顶部,并且应该记录最新的 undefined 值,因为在上面的示例中注销了 20。但它会注销 10.Why?

function show() {
  var x = 10;
  if (true) {
    var x;
  }
  console.log(x); // 10
}

show();

标签: javascripthoisting

解决方案


MDN - var:

即使在严格模式下,使用 var 的重复变量声明也不会触发错误,并且变量不会丢失其值,除非执行另一个赋值。

因此,除非您为 重新分配任何值,否则x用声明的变量var将保留其值。

x在块内重新声明if不会创建新变量;x只创建一次。

来自Ecmascript spec - 14.3.2 Variable Statement:

var 语句声明了范围为正在运行的执行上下文的 VariableEnvironment 的变量。Var 变量在它们包含的环境记录被实例化时创建,并在创建时初始化为 undefined。在任何 VariableEnvironment 的范围内,一个通用的 BindingIdentifier 可能出现在多个 VariableDeclaration 中,但这些声明共同只定义一个变量

这就是为什么x在下面的声明中

var x;

不会用undefined;隐式初始化 这个重新声明语句没有重新创建变量x

function show() {
  var x = 10;
  if (true) {
    var x = undefined; // re-assigned
  }
  console.log(x);
}

show();


关于提升的注意事项:除非您已经知道这一点,否则变量不会从字面上提升/移动到声明它们的范围的顶部;变量声明在代码执行之前被处理,这就是为什么它们似乎已经移到了范围的顶部。

有关更多详细信息,请参阅:MDN - var hoisting


推荐阅读