Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

And I thought I understood scope

Tags:

javascript

Can someone please tell me why the last logging of 'x' equals 0 and not 1. I thought because it's declared outside of a function it has global scope and then in the function it's value is set to 1 and that value would remain as it's a global? I know the first 'x' value inside the function is a global as any variable declared without the var keyword becomes a property of the window object. Many thanks

var x = 0; //global variable

function y(){
  x = 1;
  log("1. %n ", x);//1. 1

  var x = 2;
  log("2. %n ", x);//2. 2
}

y();
log("3. %n ", x);//3. 0
like image 341
screenm0nkey Avatar asked Jul 27 '10 15:07

screenm0nkey


2 Answers

The var statement is subject of hoisting, when your code is evaluated it actually looks like this:

var x = 0; //global variable
function y(){
  var x; // local!!

  x = 1;
  log("1. %n ", x);//1. 1

  x = 2;
  log("2. %n ", x);//2. 2
}

y();
log("3. %n ", x);//3. 0

Just before y is executed, a new execution context is setup, and the Variable Instantiation process takes place before the function is executed.

That's one of the reasons about why JSLint recommends only one var statement per function, to resemble what is actually happening.

like image 189
Christian C. Salvadó Avatar answered Sep 24 '22 04:09

Christian C. Salvadó


The variable x inside the function is created immediately when the function is executed and not just when the line with the variable statement is reached:

If the variable statement occurs inside a FunctionDeclaration, the variables are defined with function-local scope in that function […]. Variables are created when the execution scope is entered. […] Variables are initialised to undefined when created. […]

You can see that x is initially undefined when adding a log call in front of the first assignment:

function y(){
  log("0. " + x);//0. undefined
  x = 1;
  log("1. " + x);//1. 1
  var x = 2;
  log("2. " + x);//2. 2
}

That means both assignments inside the function refer to x in the function-local scope and not to x in the global scope.

like image 40
Gumbo Avatar answered Sep 21 '22 04:09

Gumbo