-1

So,I am trying to grasp the concept of scope chain in javascript and therefore I created the following example to check if I got it right.
Note: I am familiar with the following concepts(Execution Contexts and Lexical Environments).

Example:

function test(){
    function test2(){
        //This prints 2 as expected
        console.log(a);
    }
    //This should print 1 but instead it prints undefined
    console.log(a);
    var a = 2;
    test2();
}

var a = 1;
test();

if for example I comment the following:

//var a = 2;

Then the output in both cases is 1.

sterg
  • 57
  • 1
  • 6
  • Because JavaScript variables are hoisted. The `var a` inside your functions will be references even before you get to it in execution. The `console.log(a)` inside your function and the `a` inside `test2` refer to the local `a` (*which is still `undefined`*) and not the global `a`. – Spencer Wieczorek Mar 04 '17 at 21:41
  • I know that they are hoisted.What about the references I get from the outer environment though? – sterg Mar 04 '17 at 21:46

1 Answers1

1

You should take a look into Hoisting Concept in JavaScript. the JS engine will move all declaration in the top of the block before going into the execution step.

About your exemple :

function test(){
    function test2(){
        //This prints 2 as expected
        console.log(a);
    }
    //This should print 1 but instead it prints undefined
    console.log(a);
    var a = 2;
    test2();
}

var a = 1;
test();

will be treated like this

var a; // initialized to undefined
function test(){
    var a; // initialized to undefined [which is printed]
    function test2(){
        //This prints 2 as expected
        console.log(a);
    }
    //This will print undefined which is the actual value of a
    console.log(a);
    a = 2;
    test2();
}

a = 1;
test();

that's why it print undefined

  • What about the references I get from the outer environment though? – sterg Mar 04 '17 at 21:48
  • I dislike the term "hoisting" as it introduces confusion as the OP has demonstrated. I prefer to explain it as the EMCA-262 does, that is that all declarations are processed when entering an execution context and before execution begins, and assignments are made where they appear in the code during execution. Longer perhaps, but easier to understand I think. ;-) – RobG Mar 04 '17 at 21:49
  • when using a variable in JS, the engine will search in the local block or the current closure before going to the outer environment, as you see in the second version of the code `var a;` is hoisted and declared locally with initial value `undefined` – Mohamed El Amine DADDOU Mar 04 '17 at 21:53
  • So a quick fix as I can conclude is to convert this: var a = 2; to just a = 2; – sterg Mar 04 '17 at 21:55
  • Yes, by doing `a = 2` will set the outer `a` and your code will work as expected – Mohamed El Amine DADDOU Mar 04 '17 at 21:59