Let, Const & Var — Hoisting in Javascript

Suraj Rane
5 min readDec 12, 2021

--

One of the features that came from the ES6 release was the addition of ‘let’ & ‘const’ for variable declaration. Before that, we were used to using ‘var’ for variable declaration.

So before looking at the difference in the hoisting of var, let & const we will have a look at what hoisting is.

“What is Hoisting?”

This is one of the most common questions in javascript interviews where few candidates explain it as the Javascript phenomenon by which we can use variable’s even before declaration.
If the question is extended and asked how this works most of them will state it as the behavior of Javascript engine, moving all variable declarations (including function declarations) to the top of the current script. As all variable & function declarations are now at top of the current script it won’t throw any error.

After giving this answer definitely your interviewer won’t be much impressed :-)

So let’s see how we can give crystal clear answer to this question!

Hoisting is a phenomenon in Javascript by which you can access the variables or functions even before they are initialized. The complete javascript code is been parsed before execution & memory is allocated to the variables & functions.

Let's consider below code example

console.log(a);
var a = 10;

Here we have tried to print variable ‘a’ before declaring it. It would have thrown an error in other programming languages, but in javascript due to hoisting the above code will not throw any error and will be executed. So the candidate will say that due to hoisting, javascript engine internally will transform the above code example as -

var a;
console.log(a);
a = 10;

But, this is not the case!

Yes, looking at the above code and functional meaning of Hoisting it seems to be working in the above way but behind the scenes, it works differently.

So let’s see how the above code worked without throwing any error.

This is because before the code execution actually started the complete code was parsed and memory was been allocated to variable ‘a’ in the global scope and a placeholder value ‘undefined’ was stored in the variable till its initialization.

If we add a debugger to the first line of the code we can check in the global scope before the code execution starts.

Now the execution of code start’s and once the execution of line 2 is completed, the variable gets initialized with value 10.

This was how hoisting works behind the scene for var. Now the next question from the interviewer could be -

“Are Let & Const variables hoisted?”

The answer for it would be - technically yes, let & const are hoisted but it's not similar to var hoisting.

Let’s see how let & const are hoisted differently than var. We will use the same example here-

console.log(a);
let a = 10;

Any predictions what the output could be…..?
.

.

.

.

.

So the output would be

ReferenceError

Strange right! For similar code using ‘var’ we didn’t got any error but using ‘let’ we got a Reference error.

Why reference error?? Wasn’t our let variable hoisted??
Let’s add a debugger before the execution starts and check if memory was allocated to ‘a’.

The above image shows that variable ‘a’ was hoisted and ‘let’ being blocked scope, memory was assigned to ‘a’ in the script scope.
So why did it gave reference error?

Let’s deep dive to find out the cause for the reference error.

Hoisting definition on MDN for let & const states that

Variables declared with let and const are also hoisted but, unlike var, are not initialized with a default value. An exception will be thrown if a variable declared with let or const is read before it is initialized.

This is because the let/const variables are said to be in a “Temporal dead zone” (TDZ) from the start of the block until the initialization has been completed. So whenever we try to access any variable in temporal dead zone it will throw reference error.

Let’s understand the meaning of “Temporal dead zone”. Temporal means ‘Time’. As the zone depends on order of execution(time) rather than the order in which code is written(position). TDZ starts at the beginning of scope & ends when variable is initialized.

Have a look at the below code, it works without any error.

//Tempral dead zone for variable starts here at beginning of scope
const myFunc = () => console.log(a);

//If tried to access variable within the TDZ it will throw reference error

let a = 3; // Variable initialized here so it's end of TDZ
myFunc(); // Called outside TDZ!

Though it looks like the myFuncis using the let variable before initialization but the function is been called after the TDZ has ended. So it didn’t gave any error.

So this was how let & const variables are hoisted in javascript. Now the next time you will face questions on hoisting you could explain all this stuff which goes on behind the scenes!

I hope you have understood the hoisting concept in more detail now. Thanks for reading! Happy coding folks!

--

--