Let us try and better understand how scoping works in javascript. Scope in JS is functional, which means that a variable declared within the scope of a function is accessible only within the function.
msg = 'Global';
function testScope(){
console.log('Printing inside the scope - ' + msg);
}
testScope();
Try it in JSBin
Variables declared without the prefix var
are treated as global variables. No surprises here, the console logs the message Printing inside the scope - Global
as there is no local variable msg
.
function testScope(){
var msg = 'Local';
console.log('Printing inside the scope - ' + msg);
}
testScope();
Try it in JSBinLocal variables take precedence over global ones, and so the console logs the message Printing inside the scope - Local
, as it is able to find a local msg
.
msg = 'Global';
function testScope(){
console.log('Printing inside the scope - ' + msg);
var msg = 'Local';
console.log('Printing inside the scope - ' + msg);
}
testScope();
Try it in JSBinThis code has a gotcha. It is expected that the first message would log as Global
, since there's no local msg
yet, and once msg
is declared, the second message is logged as Local
. However, as mentioned earlier, JS has functional scope. The variable declaration is hoisted, but the initialization is not.
For those unfamiliar with the concept of hoisting, in a nutshell, hoisting means that declarations like var x; var y;
, regardless of where they are placed in a block of code, are hoisted to the top of the scope. So just because msg
is declared after the first console.log
, this doesn't mean that the console is not aware of the existence of an msg
. Due to hoisting, the scope is quite aware that msg
exists.
So why doesn't it log Local
in the console?
This is because only variable declarations are hoisted, and not initializations. So a var x = 7;
is hoisted to the top of the scope as var x = undefined;
while the inititalization of x = 7;
shall still take place only after the first console.log
Thus, due to hoisting the above code is equivalent to the following code, which explains why the console logs the messages the way it does.
msg = 'Global';
function testScope(){
var msg = 'undefined';
console.log('Printing inside the scope - ' + msg);
msg = 'Local';
console.log('Printing inside the scope - ' + msg);
}
testScope();
Try it in JSBin
Feel free to get back to me with any doubts or clarifications. I shall try my best to answer each one of them personally.