7

I was studying the concept of variable scope in JS, found this example on it:

(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
})();

output of this function is

1 
3

Now I am confused how come foo gets gets value 3 in second log. even when foo is declared by using var in if statement. shouldn't the foo declared in if will have a new instance as it gets in bar()??

agconti
  • 17,780
  • 15
  • 80
  • 114
Bharat Soni
  • 2,824
  • 6
  • 23
  • 48
  • 1
    JavaScript has function-level scope, not block-level one. The `var` inside the `if` is counted the same way as the `var foo`. – Bergi Feb 25 '14 at 17:47
  • Curious why the downvoters are downvoting. It's not a bad question. Duplicate perhaps, but not bad. Some questions deserve both downvotes and close votes. But good questions that have been asked before should be marked as duplicate. And great questions that have been asked before should be marked as duplicate and **upvoted!** This question has a clear and concise code example along with a well articulated question. This is a *great* question, albeit duplicate. The linked duplicate is *not* great: it lacks a code sample and asks multiple questions. Perhaps it should be closed as "too broad". ;) – gilly3 Feb 25 '14 at 18:01
  • I agree, it's a good, duplicate question. I'll upvote and vote for closure then. – chryss Feb 26 '14 at 00:16

2 Answers2

8

if does not introduce a scope block (I understand it does in some langauges). In JavaScript, only function() {} creates a scope block.

Niet the Dark Absol
  • 320,036
  • 81
  • 464
  • 592
3

There are only two kinds of scope in Javascript; function scope and global scope.

The code inside the if statement doesn't have a scope of its own, so the variable inside the if statement is the same one as the one outside it.

Declaring a variable more than once in a scope doesn't create more than one variable. The var keyword inside the if statement is ignored as the variable already is declared once in the scope, so it's just an assignment.


Note also that the declaration of variables is hoisted to the top of the scope, so even if a declaration is inside a code block that is not executed, the variable is still created:

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
Guffa
  • 687,336
  • 108
  • 737
  • 1,005
  • "There are only two scopes ..." No. Two *kinds* of scope would be more accurate, but to say that there are only two scopes is just confusing. – gilly3 Feb 25 '14 at 17:50
  • @gilly3: Yes, you are right, that is clearer. – Guffa Feb 25 '14 at 17:51