sivabudh
sivabudh

Reputation: 32635

Puzzled by this JavaScript code snippet

For this snippet, I'm not surprised global variable 'a' evaluates to be 5.

http://jsfiddle.net/MeiJsVa23/gZSxY/ :

var a = 10;

function func(){
  a = 5;
}

func();   // expect global variable 'a' to be modified to 5;

alert(a); // and this prints out 5 as expected. No surprise here.
​

But how come for this code snippet, global variable 'a' evaluates to be 10 and not 5? It's as if the a = 5 never happened.

http://jsfiddle.net/MeiJsVa23/2WZ7w/ :

var a = 10;

function func(){
  a = 5;
  var a = 23;
}

func();   // expect global variable 'a' to be modified to 5;

alert(a); // but this prints out 10!! why?

Upvotes: 7

Views: 176

Answers (6)

ZER0
ZER0

Reputation: 25322

So, there are two things are going here: hoisting and shadowing.

Because the first one, variable declarations are "hoisted" to the top, so your code is equivalent to:

var a = 10;

function func(){
    var a;
    a = 5;
    a = 23;
}

And because the second one, you're "shadowed" the global variable a with a local ones, so the changes are not reflected to the global a.

Upvotes: 2

millimoose
millimoose

Reputation: 39950

Presumably, the statement var a = 23 creates a local variable for the whole scope. So the global a is shadowed for the entirety of func(), not just for the lines below the statement. So in your second snippet, a = 5 is assigning to the local variable declared below.

Upvotes: 0

gen_Eric
gen_Eric

Reputation: 227190

This is called "variable hoisting". var declarations (and function() declarations) are moved to the top of their scope.

Upvotes: 1

Naftali
Naftali

Reputation: 146302

var a = 10;  //a is 10

function func(){
  a = 5; //a is 5
  var a = 23; // a is now in local scope (via hoisting) and is 23
}

func();   

alert(a); // prints global a = 10

Upvotes: 0

Mitya
Mitya

Reputation: 34556

This has to do with hoisting.

In the function, a local variable with the same name is declared. Even though it happens after your modification, it is deemed to have been declared before it - this is called hoisting.

Local variables hoist for declaration but not value. So:

function someFunc() {
    alert(localVar); //undefined
    var localVar = 5;
}

Functions, if declared with function name() {... syntax, hoist for both declaration and value.

function someFunc() {
    alert(someInnerFunc()); //5
    function someInnerFunc() { return 5; }
}

Upvotes: 0

Graham
Graham

Reputation: 6562

This is due to variable hoisting: anything defined with the var keyword gets 'hoisted' to the top of the current scope, creating a local variable a. See: http://www.adequatelygood.com/2010/2/JavaScript-Scoping-and-Hoisting

Upvotes: 11

Related Questions