An in-depth understanding of Hoisting in JavaScript

Understanding Hoisting in JavaScript


This article is for JavaScript developers who want a deep understanding of the core concept of the language and how the javascript engine work. Though var and let are standard keywords for variable declaration in JavaScript, at the end of this tutorial, you will know why let is of more preference than var.

Is it true that the JavaScript program is interpreted line by line, from top to bottom as it executes? Yes, it is true but this assumption can be proved otherwise. Let’s take a look at this code:

age = 10;
var age;
console.log( age );

What do you expect from the console to output?

a: 10 b: undefined

The console will output 10. In javascript, if a variable is assigned a value without being declared, it is implicitly declared also by default, a value of undefined is assigned to a variable declaration. Some JavaScript developers with this knowledge will expect the console to output undefined since age = 10 comes before var age. Naturally, they assume that age is reassigned with a default value of undefined which is incorrect.

Let me show you how the JavaScript engine process codes.

console.log( boys );
var boys = 20;

Before then, what do you think the console will output? Some persons would expect the output to be a ReferenceError since the variable boys is being used before it is declared. Unfortunately, that assumption is incorrect. The correct output will be undefined.

The JavaScript interpreter runs through the whole codes first and declares all variables and functions at the top of the current scope before executing the program.

In order to have a better understanding of how the javascript engine process codes, we will use a banana for our illustration.

An image of a half peeled and  cut banana

For one to eat a banana, it must be peeled first before consumption takes place. So variable declaration comes first (peeling of the banana) before any other piece of code is executed(consuming the banana).

Javascript engine

Our first code snippet is processed by the engine like this:

var age;
age = 10;
console.log( age );

Where line 1 and 2 are compilation while line 3 is execution. Similarly, our second code snippet is processed as:

var boys;
console.log(boys);
boys = 20;

We can see that the engine moves all declarations (both variables and functions) to the top of the scope while every other piece of the code remains in its position. The concept is known as Hoisting.

From the code snippet above, the function declaration is hoisted that is why the function call is executed.

Is function expression hoisted? Let’s see.

countryName ();  // TypeError!
var countryName = function country () {
    console.log( "Nigeria");
}

What happened! Why TypeError and not even ReferenceError can someone help me? Calm your nerves, my friend, I got you covered.

Now, from our previous discussions, we said that variable declarations are hoisted while every other piece of the code remains in its position. So let’s hear from the JavaScript engine.

Javascript engine:

var countryName;  // default value is undefined.
countryName ();  // TypeError
country ();  // ReferenceError
countryName = function () {
    var country = "everything within this scope";
    console.log( "Nigeria");
}

From the code snippet above, line 2 executes a value of undefined and that’s why we got the TypeError and line 3 cannot reference the country because it is in a lower scope.

As we saw earlier, both function declarations and variable declarations are hoisted but which one is hoisted first?

countryName ();  // India
var countryName;
countryName = function () {
   console.log( "Nigeria");
}
function countryName () {
    console.log( "India");
}

Our console outputs India. The code snippet above is a confirmation that function declarations are hoisted first.

While duplicate variable declarations are ignored, duplicate function declarations override one another.

Let’s confirm this statement:

countryName ();  // Ghana
var countryName;
countryName = function () {
    console.log( "Nigeria");
}
function countryName () {
    console.log( "India");
}
function countryName () {
    console.log( "Ghana");
}

But what can we say about the ES6 let, class and const declarations? Are they hoisted too?

Of course! Yes, they are hoisted. But in a different manner. The JavaScript compiler does not move the ES6 declarations to the top of the scope rather it creates memory space for them.

Furthermore the instance of var and let can be initialized without value but const cannot. If var is used without an assigned value, it will return undefined but with let, we will receive a ReferenceError.

Why is let consider more save than var?

Declarations made with var can be accessed and mutate anywhere outside the initial scope while declarations made with let and const cannot.

Since is javascript is getting better and with its improving features, the new ES6 let is considered more reliable than the old var.

Conclusion

The concept of Hoisting in JavaScript could be so tricky if not simplified. Hoisting is a great feature in Javascript which makes it so unique. In order to write clean codes with javascript, one must understand Hoisting. This article is written to demystify Hoisting in Javascript.


Share on social media

//