2

I have been playing around with some pointless logic and scopes and have noticed some strange behavior which has confused me...

        var test = 1;
        (function(){
            console.log(test); //its 1
        })();

        var test = 1;
        (function(){
            console.log(test); //its 1
            test = 2;
        })();

        var test = 1;
        (function(){
            console.log(test); //Uncaught ReferenceError: test is not defined
            var test = 2;
        })();

In the following examples I would of expected the last function to log out 1 until test is reassigned in that scope however it is undefined, if I remove the scoped declaration and reassign the top level test it then logs out 1 as expected.

Can anyone explain why that last examples test becomes undefined?

Simon Staton
  • 4,345
  • 4
  • 27
  • 49
  • The last should just echo "undefined" and not throw an error. – Sirko Feb 05 '15 at 14:42
  • It's not because you're assigning it (apparently, as can be seen from #2), but because you are *declaring* it in that scope. – Bergi Feb 05 '15 at 14:44
  • Because javascript doesn't have block scope when you define variables. And you override the value of test = 1 with the second declaration which is hoisted at the top of the function. – Ioan Feb 05 '15 at 14:44

2 Answers2

1

The last snippet is roughly equal to

var test = 1;
(function(){
   var test; // it is undefined here as it is not initialized yet
   console.log(test); // undefined
   test = 2; // initialized
   console.log(test); // hence 2
})();

due to the fact that the variable declaration is hoisted to the top of the function. So, when you log test it is undefined and is over-shadowing the test which is outside.

Amit Joki
  • 58,320
  • 7
  • 77
  • 95
0

A really nice article explaining what happens (and many details!):

Function declarations and variable declarations are always moved (“hoisted”) invisibly to the top of their containing scope by the JavaScript interpreter.

This is why you cannot access the global variable before the declaration of the local one. This would be a weird thing to access two different variables with the same name in the same scope no?

Gnucki
  • 5,043
  • 2
  • 29
  • 44