CoderBear's Blog
Understanding scope in Javascript
June 5, 2015

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 JSBin

Local 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 JSBin

This 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.



Receive my blogs in your email. Subscribe.

Only Javascript. No Spam. Promise.