2014-02-25 51 views
4

我正在学习在JS变量的作用域的概念,发现它这个例子:该功能的变量的作用域混乱的JavaScript

(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 
3 

现在我很困惑怎么来的foo在第二个日志中获取值3。即使在if声明中使用var来声明foo时也是如此。在if中声明的foo不应该有一个新的实例,因为它在bar()

+1

JavaScript具有功能级范围,而不是块级功能。 'if'内的'var'与'var foo'的计数方式相同。 – Bergi

+0

好奇为什么downvoters downvoting。这不是一个坏问题。也许重复,但不坏。有些问题值得赞同和接近的投票。但之前提出的好问题应该标记为重复。以前曾经问过的很多问题应该被标记为重复和** upvoted!**这个问题有一个清晰简洁的代码示例以及一个明确表达的问题。这是一个很好的问题,虽然是重复的。链接的副本不*很好:它缺少代码示例并提出了多个问题。也许它应该被封闭为“太宽泛”。 ;) – gilly3

+0

我同意,这是一个很好的重复问题。然后,我会赞成并投票结束。 – chryss

回答

3

Javascript中只有两种范围;函数范围和全局范围。

if语句中的代码没有自己的范围,因此if语句中的变量与外部语句中的变量相同。

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


还要注意,变量的声明被提升到的范围的顶部,因此,即使一个声明是不执行的代码块内,仍然是创建该变量:

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 
+0

“只有两个示波器......”第二种*类型的示波器会更准确,但要说只有两个范围只是令人困惑。 – gilly3

+0

@ gilly3:是的,你说得对,那就更清楚了。 – Guffa

8

if没有引入范围块(我理解它在某些语言中的确存在)。在JavaScript中,只有function() {}创建一个范围块。

+0

“我了解它在某些语言中”哪些是?只是好奇... – jeremyjjbrown

+0

@jeremyjjbrown - http://en.wikipedia.org/wiki/Scope_(computer_science)#By_language – gilly3