Random thoughts & observations

From the mundane to the profound and everything in between here’s what’s rocking our world

Understanding JavaScript hoisting

Posted: October 11, 2014
Written by: Saints At Play
Category: Javascript

Part of JavaScript's popularity is its flexibility but this can also present challenges for even the most seasoned developers, particularly when trying to understand the role of hoisting and its impact on scripting.

Take for example the following code:

if(!("a" in window))
{
 var a = 1;
}

console.log(typeof a);

Hands up who expected to see a value of Number being output to the browser console window?

Surprised to see a value of undefined being returned instead?

What about this snippet:

function displayValues() 
{
  console.log(a);
  console.log(displayNewValue());
  var a = 1;
  function displayNewValue()
  {
    return 5;
  }
}
displayValues();

Expecting to see a value of 1 followed by 5 afterwards?

Are you therefore surprised to see the value of undefined being returned first followed by a value of 5?

Read on...

Hoisting

When executing JavaScript code the JavaScript interpreter lifts or 'hoists' variable declarations to the top of the page or, if those variables are declared within a function, the top of their enclosing function. The value assignments for those variables however are NOT 'hoisted' which helps explain why, in the above examples, we see values of undefined being returned for the variables declared in each code snippet.

In short - the variable name has been lifted but NOT its value.

Function declarations however are 'hoisted' which explains why, in the second example, the return value of the function is displayed in the browser console window when the script is executed.

Not all functions are created equally though.

Function declarations, like the following, are 'hoisted':

function detectNetworkConnectivity()
{
  // Some code here
}

Function expressions though, like the following, are NOT and behave like variable declarations instead:

var detectNetworkConnectivity = function()
{
  // Some code here
}

So if we rewrite our second script example to use a function expression:

function displayValues() 
{
  console.log(a);
  console.log(displayNewValue());
  var a = 1;
  var displayNewValue = function()
  {
    return 5;
  }
}
displayValues();

We find that the following error is returned:

TypeError: undefined is not a function (evaluating 'displayNewValue()')

So how do we solve this behaviour?

The simplest and most effective way is to declare all your variables and functions, as far as is reasonably possible, towards the top of their enclosing function (or if outside of a function, towards the top of the page) with a single var statement.

By following this practice the values for those variables and functions will be immediately available upon their subsequent request later on within the enclosing function/script.

So if we were to rewrite our previous script in the following way:

function displayValues() 
{
  var a = 1,
     displayNewValue = function()
     {
       return 5;
     };
  console.log(a);
  console.log(displayNewValue());  
}
displayValues();

And then run this in the browser console window we'll see the following values being output:

1
5

Hey presto! No more hoisting problems with variable declarations or function expressions!

« Return to Posts

Comments

There are no comments

Posting comments after three months has been disabled.