javascript中的变量范围混淆

variables scope confusion in javascript

本问题已经有最佳答案,请猛点这里访问。

我在研究JS中变量范围的概念时,发现了下面的例子:

1
2
3
4
5
6
7
8
9
10
11
12
(function() {
    var foo = 1;
    function bar() {
        var foo = 2;
    }
    bar();
    console.log(foo) //outputs 1
    if(true) {
        var foo = 3;
    }
    console.log(foo) //outputs 3
})();

此函数的输出是

1
2
1
3

现在我很困惑为什么foo在第二个日志中得到值3。即使在if语句中使用var声明foo。在if中声明的foo不应该像在bar()中一样有新的实例吗??


if不引入作用域块(我理解它在某些语言中是这样的)。在javascript中,只有function() {}创建一个作用域块。


javascript中只有两种作用域:函数作用域和全局作用域。

if语句中的代码没有自己的作用域,因此if语句中的变量与它之外的变量相同。

在作用域中多次声明变量不会创建多个变量。if语句中的var关键字被忽略,因为变量已经在作用域中声明了一次,所以它只是一个赋值。

还要注意,变量声明被提升到作用域的顶部,因此即使声明位于未执行的代码块中,仍然会创建变量:

1
2
3
4
5
6
7
8
9
10
var foo = 1; // a global variable
(function() {
  console.log(foo) //outputs"undefined"
  foo = 2; // sets the local variable
  if(false) {
    var foo = 3; // creates the local variable, but the assignment never happens
  }
  console.log(foo) //outputs 2
})();
console.log(foo) //outputs 1