1

foo will lookup b value with 2 as expected when executing in console

function foo() {
    console.log(b)
}
var b = 2
foo() // 2 for console.log

but when I do this

function foo() {
    console.log(b)
    var b = 2
    console.log(b)
}
var b = 2
foo() // undefined for first console.log

it won't lookup b in global scope anymore why ?

Chris Martin
  • 30,334
  • 10
  • 78
  • 137
user310291
  • 36,946
  • 82
  • 271
  • 487
  • Funny that regardless of how often such questions are answered, posters would rather answer the question (or post a comment…) than search for a suitable answer and close it as a duplicate. – RobG Dec 24 '14 at 11:01
  • I marked a poor duplicate, there's a better one here if someone else wants to close this: [*JavaScript 'hoisting'*](http://stackoverflow.com/questions/15311158/javascript-hoisting). – RobG Dec 24 '14 at 11:11
  • The direct answer to the question is: Because it's shadowed by b in the local scope. – Chris Martin Dec 24 '14 at 11:16

1 Answers1

6

It is because of what is called Javascript Hoisting, this is how javascript sees your code:

function foo() {
  var b; // javascript hoisted this variable on top
  console.log(b) // so here you see underfined
  b = 2;
  console.log(b);
}

Now because javascript hoised variable b on top of function, your global variable b was never used and hence statement immendiately after hoisted variable showed undefined. So if you remove new declaration (var keyword) from your function, you should still have access to global b variable.

BTW, it is good practice to declare all your variables on top of function like:

function foo() {
  var b = 2;
  console.log(b);
}

To know more on the topic, see this:

Dev01
  • 4,082
  • 5
  • 29
  • 45
  • "Hoisting" is jargon, and misleading to me. What actually happens is that variable declarations are processed after the entire program is parsed but before any code is executed. But yeah, "hoisting" seems to be the popular term for that. – RobG Dec 24 '14 at 11:05