Thursday, September 22, 2016

JavaScript: Variable Hoisting

JavaScript makes two passes. During first pass,  js gathers all variable declarations (NOT assignments) and function definitions. In the second pass, js executes the code taking information learned in the first pass into consideration.

Code example

(
function()
  {
  console.clear();
var i = 100;
console.log("S1.1 topmost: i = " + i);  
 
    function doIt1() {
      // NO other variable with name i is declared in this function
      //  therefore, i refers to i declared in the enclosing function
    console.log("S2.1 doIt1: i = " + i);
      // this corresponds to function scope
      //   no var named i declared in this function
      //   this has function scope
      console.log("S2.2 doIt1 (using this): i = " + this.i);
      // NOTE: var keyword is NOT used
      //    changes value of i declared in enclosing function
      i = 400;  // changes value of i defined in enclosing function
      console.log("S2.3 doIt1: i = " + i);
    }
 
    function doIt2() {
      // i is the var defined below (equals undefined so far)
      //   i is NOT the i declared in enclosing function
    console.log("S.3.1 doIt2: i = " + i);
      // this refers to i defined in this function
      console.log("S.3.2 doIt2 (using this): i = " + this.i);
      // i is declared in this function scope
      //   NOTE the use of var keyword
      //   hides i declared in the enclosing function
      // i is hoisted to the top of this function
      //   at the top of this function, i has value of undefined
      // now assign it a value
      do{
        // i is declared at function scope
        //   even though it is within the curly braces of while
        var i = 500;
      } while(false);
      // value is assigned to the local i
      console.log("S1.2 doIt2: i = " + i);
    }
 
    doIt1();
    doIt2();
 
    // i retains the value assigned in doIt1
    console.log("S1.3 topmost: i = " + i);
    console.log("this.xxx limits scope to the current function's curly braces!")
  }
)();

Output

S1.1 topmost: i = 100
S2.1 doIt1: i = 100
S2.2 doIt1 (using this): i = undefined
S2.3 doIt1: i = 400
S.3.1 doIt2: i = undefined
S.3.2 doIt2 (using this): i = undefined
S1.2 doIt2: i = 500
S1.3 topmost: i = 400
this.xxx limits scope to the current function's curly braces!