Open In App

How does JavaScript Hoisting work internally ?

Improve
Improve
Like Article
Like
Save
Share
Report

In simple terms, hoisting in JavaScript refers to the fact that variables can be used before they’re declared. The declared variables are somehow virtually moved to the top of the scope. However, hoisting applies only to variable declarations and not to variable initialization. 

While almost anyone with a little bit of experience in JavaScript knows what hoisting is, many of them don’t really know why it happens and why it behaves the way it does.

The reason why JavaScript behaves this way with regard to declarations lies in the underlying mechanism of how the JavaScript engine executes code. Therefore, in order to really get a feel of how Hoisting happens, we need to get into the behind-the-scenes of code execution in JavaScript

Everything in JavaScript happens inside what is known as an Execution Context. An execution context can be thought of as an environment that tracks the evaluation of code during run time.

An execution context has 2 main components:

  1. Memory Component: Stores the variables and functions as key-value pairs.
  2. Code Component: Code is executed one line at a time.

To see how Hoisting actually happens using this execution context, let’s see an example. Consider the following simple JavaScript code: 

Javascript




console.log(x);
x = 7;
console.log(x);
var x;


Here, the variable x is being used (being printed and being assigned a value) before it is declared. If we apply the concept of hoisting, we can easily judge the output of the above code as:

undefined
7

However, let us understand how we got this output using execution context. 

The creation of the global execution context corresponding to the code shown above will happen something like this: First, the Memory allocation phase will occur in which any variables/functions present in the code will be scanned and allocated memory. Since there are no functions in the code, the variable x will be allocated space in memory and assigned the undefined placeholder. The global execution context after this step will look something like this:

Global Execution Context after memory allocation

Now, the code execution phase will begin inside the code component, in which the code will be executed from the beginning, one line at a time. So, first of all, the value of the variable x that is undefined will get printed on the console, since at this stage the value stored for variable x is undefined. Then in the next step, the value 7 will be assigned to x. After these two steps are done, the updated execution context will look something like this: 

Global Execution Context after the first two lines are executed.

In the next line, we’re again printing the value of x. Since now the value of x is 7 (as can be seen in the figure above), 7 will get printed on the console. The final line is actually the declaration line which was done at the beginning itself. 

Thus, the final output for the code we wrote above, would be:

undefined
7

This is exactly what the expected output was. So with the help of this simple example, we understood what hoisting actually means and how it actually happens internally. 

The reason why the variable declarations appear to move to the top of the code is now evident by the working of the two phases within the execution context. Before any code is executed, all the variables present in the code will be allocated memory and assigned the value undefined (that is declarations are being considered first before any other code). Only after this is done, the code that is using that variable will get executed in the second phase. This also explains why variable initialization is not hoisted. This is because variable initialization basically means ‘using’ a variable and so it will get executed only in the second phase which is code execution. 


Last Updated : 24 Mar, 2022
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads