Hosting the Hoisting in JavaScript
Hoisting in JavaScript is therefrom always but has come into the limelight after the ES6 changes. In ES6 we saw two new keywords let and const which avoid the hoisting.
Disclaimer: let and const also perform hoisting. How???? Will see that as well.
You will see a lot of tutorials and blog mentioning that Hoisting in JavaScript means when the program runs, JavaScript moves all the variable declaration at the top and blah blah…but trust me it doesn’t, it seems like that only but under the hood, it is not true.
I promise by the end of this article you’ll understand it very clearly and will never get it wrong in interviews.
Before starting, predict the output of the below sample codes:
var name;
console.log(name);//Outputs undefined on the console as it has been declared but not initialized.
So we saw that when we declare a variable but not initialize it, that variable holds the value undefined.
var fname="sourabh";
console.log(fname);//You predicted the output as sourabh. Good Job!console.log("first - "+lname);
var lname="gupta";
console.log("second - "+lname);//The ouput will be first - undefined and second - gupta.//Amazed? Bear with me, you'll get your answer!!
Let’s see what happens when we try to call a function before its declaration.
printName();function printName(){
console.log("sourabh")
}//The output will be sourabh.
You might be thinking what’s wrong with the statement that while running JavaScript moves all the variable and function declarations at the top, variables get undefined and functions are made ready to use. Hold On!! We’ll come to it.
Unlike all other programming languages, we can use the functions and variables in JavaScript even before the declaration.
What happens is that just before running our code, the whole JavaScript file is scanned and an execution context is created.
All the variables and functions get some memory allocated in that execution context but there’s a slight difference when variables get some memory into the global execution context they don’t get initialized whereas when the functions do they are made ready to use as well.
One more example,
console.log(middleName);//It gives the error on the console as the variable we are trying to access is not declared anywhere in the program.
But I said that we can access the variable even before declaring them, Yes, We can but there’s a condition, we can access the variables and function before declaring them but they have to be declared somewhere in the code.
I repeat functions get memory allocated in the execution context and are made ready to use whereas variables are just declared but not initialized. Remember this statement we’ll come back to it again.
That was just a spoiler, Let’s dive deep into the Hoisting with some example codes.
//Suppose we have a function to double a numberfunction doubleNumber(num){
console.log(num*2);
}doubleNumber(5);//Outputs 10 on console. WELL AND GOOD!!
Let’s try to move the function call above the function declaration.
doubleNumber(5);function doubleNumber(num){
console.log(num*2);
}//Outputs 10 on console. STILL AS EXPECTED!!
Stay there with me, you might have seen the function expressions in JavaScript as shown below.
//Function to double a number stored in variable doubleNumbervar doubleNumber = function (num){
console.log(num*2);
}doubleNumber(5);//Outputs 10 on console. THINGS STILL THE SAME!!
This is also a valid code. Right?
If we rewind two steps we made a function call before the declaration of the function. Let’s do it again function expressions way.
//Function to double a number stored in variable doubleNumberdoubleNumber(5);var doubleNumber = function (num){
console.log(num*2);
}//ERROR : doubleNumber is not a function.
doubleNumber is not a function, So what it is? Let’s check that out.
console.log(doubleNumber);var doubleNumber = function (num){
console.log(num*2);
}//Outputs undefined on the console.
Ohh…It was a valid JavaScript function expression but giving an error. What happened now? Now let me again remind you of the statement.
The functions get memory in the global execution context and made ready to use but variables are just declared not initialized. So the doubleNumber which we are trying to call is stored in the memory as a variable, not a function.
Got my point?
So what happens when we declare a variable in JavaScript using the var keyword, JavaScript itself hoists them i.e. even before the code is run the whole JavaScript code is scanned and memory gets allocated to all the variables in the execution context and we can access them anywhere in the code.
One last thing I mentioned a disclaimer in the starting that variable declared using let and const also gets hoisted. Let’s see…
console.log(a);let a = "hello";// ReferenceError: Cannot access 'a' before initialization
In the above example, a can’t be accessed before initialization that means let doesn’t get hoisted and I was wrong. No!!
Let’s have a look at the below code,
console.log(a);// ReferenceError: a is not defined
If you notice carefully both the codes have different errors
- Cannot access ‘a’ before initialization
- a is not defined
That means in the first code, JavaScript knew that there’s a variable named “a” in the program but it is not allowing us to access that before initialization, this concludes that the variable declared using let and const also gets hoisted.
So when we declare variable using let and const, those variables also get memory allocated in the execution context but they stay in Temporal Dead Zone and that is why they can not be accessed before initialization.
We won’t go deep into Temporal Dead Zone here because it is another topic that deserves a separate article and including that here will make this article much longer.
So if we talk about Temporal Dead Zone (TDZ) in short it describes that the variables are in scope, but they aren’t declared.
Do read more about this sci-fi term Temporal Dead Zone (TDZ) here.
That’s all for Hoisting. Hope I was able to make you understand and you won’t have to look somewhere else for Hoisting now.
Reading is good but reading with implementation is great !
Suggestions and critics are always welcome.