What is Hoisting in Javascript?
The mechanism of giving memory to the variables in the creation phase is called as Hoisting.
Let’s understand this by some example.
var a = 25; console.log(a); Output: 25
In the above example you can see we have just declared one variable a and assign it a value 25. And we simply log it. So there is nothing an unexpected about the result it will simply print the 25 in the console.
Now let’s do one thing.
// var a = 25; console.log(a); Output: // ReferenceError: a is not defined
Here we have commented out the first line and just log the a. So you might aware what will be the output here. Yes the output will be reference error.
Now let’s do the minor change in the code.
console.log(a); var a = 25; Output: undefined
Now here in the first line you can see a is not present there. a is there after line no 1. So how it is printing undefined? Should not it be same as reference error like previous example? Because it is not defined before first line. So the reason because of you getting the undefined is Hoisting.
How Hoisting works?
As we know there is two phases of execution context. Creation phase and execution phase. So will understand hoisting by using these only.
When our code is in creation phase , that time javascript engine scans the entire code , so it will check for all the global variables. And it assign space for them. And javascript engine simply put undefined there. The value is actually given in the execution phase.Javascript engine does not care about the value in creation phase. It care about value only in execution phase.
Since the value is not given to the variables in the creation phase hence it is called as partially hoisted. Because they are given space but they have not assigned any value.
Function Hoisting
function hoisting() { console.log("Hello"); } hoisting(); Output: Hello
In this example nothing is an unexpected. It will simply print the output as “Hello”. Now lets do the minor change here
hoisting(); function hoisting() { console.log("Hello"); } Output: Hello
In this example we are just calling the hoisting() before declaring that function. Again it will give the same output. How is this possible? It should be undefined right? As we have learned above. Well this is giving correct output because in function hoisting when javascript look for that function in the entire code so that function is assigned the value as fn() not undefined. Undefined is assigned in case of variable only. Hence function are completely hoisted. It means in case of function memory and value both are assigned in creation phase only.
Now lets take the another example
hoisting(); function hoisting() { console.log("Hello"); } function hoisting() { console.log("Hello everyone"); } Output: Hello everyone
In the above example what will be the output and will this function hoisted twice?? Well the ans is no. Function will hoist only one but its output will be “Hello everyone”. Because here the function will override. Because when javascript engine looks for that first hoisting function, it will allocate the memory to it along with its definition.
Then again it will see the same function hoisting and it will say it is already in the memory. But since it cares about the value when it comes to this function then it will replace the console log with latest value i.e “Hello everyone”. So in the creation phase itself the first console.log will be removed and the second console log will takes place.
How hoisting works with function expression?
var hoisting = function() { console.log("Hello"); } hoisting(); Output: Hello
Here we are assigning a function to a variable , hence its called as function expression. And inside function we have just console log the hello message. In this case output will Hello. But what happened with below code , can you guess??
hoisting(); var hoisting = function() { console.log("Hello"); } Output: TypeError : hoisting is not a function
Here as you can see the output is unexpected i.e Type Error. How its possible , we just learn above that functions are fully hoisted. But Its because when javascript engine parse the file it says that hoisting is a variable. Because as we know in creation phase javascript engine does not care about the value. And as variables are partially hoisted so this hoisting variable will declared with undefined value in creation phase.
Javascript engine does not know that later it will be a function. But later when hoisting() function will called with parenthesis , how it can be use parenthesis with the variables. Thats why its giving the type error that hoisting is not a function.
Is let and const variables are also hoisted?
Whether you will use var , let and const, it is definitely going to be hoisted. But in case of let and const it is not going to initialize any value. As we have seen with var it was initialize with undefined.
Let see the below example.
console.log(a); let a = 10; or const a = 10; Output: ReferenceError can not access a before initialization
Here it will give the reference error that can not access a before initialization. Its also called temporal dead zone. Temporal dead zone is a time spend in which the variable is actually created but it is not initialized any value. As it is not initialized any value therefore you cant access it. Thats why when console log will execute at that a is not accessible because of temporal dead zone. Thats why it is recommended to use let and const.