Hoisting in JavaScript

Hoisting in JavaScript

In this article we will be discussing about one of the most initimidating features of JavaScript which is Hoisting.

What is Hoisting?

As per MDN: Hoisting refers to the process whereby the interpreter allocates memory for variable and function declarations prior to execution of the code. Declarations that are made using var are initialized with a default value of undefined. Declarations made using let and const are not initialized as part of hoisting.

Let's Understand Hoisting with an example:

image.png

If we look at the above example:

It's pretty easy to guess that the above code will output:

hoist-1.PNG

Now just tweak the code little bit like below:

image.png

The output now drastically changes:

hoist-2.PNG

This is weird!!!!! We are able to access a variable even before it stands declared. This is where the concept of Hoisting comes into play.

Important Note : To understand Hoisting one must have knowledge of Execution Context. As everything in JavaScript takes place inside an Execution Context.

Let's understand this in detail... what's going on??

As soon as the script gets loaded in browser, a Global Execution Context gets created which mainly consists of two parts namely Variable Enviornment Component and Thread of Execution Component.

Variable Environment Component contains all the variables and functions stored in the form of key-value pairs where as Thread of Execution is the place where code is executed on a line-by-line basis making JavaScript a synchronous single threaded language.

Execution Context consists of two phases Memory Creation Phase and Coding Execution Phase respectively.

In Memory Creation Phase, JavaScript Engine skims through the entire code looking for variables and functions to store them in key-value pair form. The variables are stored and assigned a value of 'undefined' where as the functions are assigned with their respective definitions. Memory Creation phase takes place even before a single line of code is being run.

The Memory Creation Phase provides us with the reason that how one is able to access a variable even before it's declared and why the variable is outputing undefined.

Now we know, why on running above code we got 'undefined' and how we were able to access variable.

Let's make some more tweaks in the example:

image.png

Can anyone guess the output of the above code:

hoist-3.PNG

As everyone can see, the weird behavior we got to see with the variable is not the case with function, we are able to access the function easily and the is also outputting the correct result as expected.

But How?

The answer to this how lies in the Memory Creation Phase of Execution Context, as we read earlier functions are assigned with their respective function definition, this means that function stands assigned even before a single line of code is being executed. As the functions are available even before a single line of code is executed, they can be called anywhere in the code even before their declaration without a problem.

Let's keep on with our tweaking work:

image.png

Can anyone guess the output:

hoist-4.PNG

Whatttt!!!!!! An error!!!!!! One must be thinking why the function didn't output the code and how does this is an error?

Why?

As we have read earlier, in the Memory Creation phase of Execution Context the JavaScript Engine skims through the code looking for variables and functions to store them in memory as key-value pair. But a function declared using functional expression declaration method is considered as a variable and assigned a value 'undefined' the function definition is not assigned to the function before execution of the code. If one tries to access that as a function even before declaration JavaScript Engine outputs a TypeError as it treats the function as a variable.

Point to Note: Functions declared as functional expression or by es6 syntax as arrow function are considered as a variable during the Memory Execution Phase of Execution Context by JavaScript Engine and are assigned with a value of 'undefined'. Hence trying to access them before declaration will result into TypeError.

So at last Hoisting in JavaScript is nothing but a way through which we can access variables and functions even before they are declared in code.