Hoisting in Javascript
How hoisting works in javascript for var, let, const, and functions.
In this blog, we will be reading about how hoisting works in the case of var, let, and const. Before starting let's understand what is hoisting? In simple terms, we can explain it like this- accessing a variable or function before declaring it in code. For example, let's take this code and its output.
CODE
console.log(x);
print();
var x = 10;
function print() {
console.log("Hello");
}
OUTPUT
undefined
Hello
In the above example, we tried logging x and calling the print function and the code runs without any error, this is because of hoisting. Lifting up variables and functions so that they can be accessed before they are declared. But how does it work? In order to know how hoisting works, we need to understand first how javascript works and how the code is executed.
How Javascript Works
Everything in javascript happens inside the execution context. An execution context can be considered as a container in which the whole javascript code is executed. The execution context has two components, first one is called the memory component or the variable environment and another one is the code component or thread of execution.
The memory component stores all the values and functions as key-value pairs whereas the code component stores the whole code to be executed line-by-line. Even before our code runs, the javascript engine allocate memory to all the variables and functions in the memory component and stores them as key-value pairs shown in the image above.
Now put a debugger on line no.3 to check the working of the memory component.
Check the global scope and find the x and print function there. We find that x is undefined and the print function is stored in the global scope even before the code reaches the line where they are declared, i.e line 6 and line 7
Now when putting a debugger on line 10 we find the x is not undefined, it has been assigned a value of 10 according to the code.
What happens in the execution context?
So what happened above is that when we run our code, the js engine first goes through the entire code and allocates memory to every variable and function. Variables are assigned a value of undefined whereas functions are stored fully.
After this our code runs line by line because javascript is a single-threaded language, when it reaches line-3 it tries to log the value of x which is stored in the global scope but its value is undefined so undefined is printed in the console and when the print function is called, it works fine because the whole function is stored as the value for the print key in the global scope.
As our code reaches line no - 6, the JS engine finds out that x has been assigned a value of 10 and therefore the value of x in global scope is changed from undefined to 10.
This is how hoisting works for functions and var.
Are let and const also hoisted?
Before we find the answer to this question, let us check with the help of code.
Code
console.log(letVariable);
let letVariable = 10;
Output
Code
console.log(constVariable);
const constVariable = 10;
Output
We get an error if we try to access the let and const variables before the declaration but this does not mean let and const are not hoisted.
On checking the source in dev tools and putting a debugger before any code is run, we find out that const and let both are not stored in the global scope but stored in a different scope called the Script and also they are assigned undefined. The reason we gets an error instead of undefined like in case of var because let and const are not stored in the global scope.
As the code reaches the line where value is assigned to let and const, value of both changes in the Script scope.
The time from which let and const are undefined to the time value assigned to them is called Temporal Dead Zone If we try to access the variable in this zone we get an error. We can reduce this by declaring all our variables at the top of our code.
Conclusion
Functions, vars, let, and const, all are hoisted but in a different way. Let and const gives an error because of the temporal dead zone. Var gives undefined if accessed before declaration whereas functions work without any problem. Happy hoisting!