Hoisting is one of those concepts in JavaScript that often confuses developers, especially during interviews. Many developers struggle to explain the difference between hoisting in var
, let
, and const
variables, and how it affects the execution of their code. This can lead to a lot of sweating and nervousness during interviews.
However, with the information provided in this article, understanding hoisting should be a breeze. By providing examples and explanations of hoisting behavior, this article aims to demystify this concept and make it easy for developers to understand and explain. Now, you'll be able to confidently explain hoisting to your interviewer and ace that interview.
Hoisting is a behavior in JavaScript where the interpreter moves variable, function, and class declarations to the top of their scope, before execution of the code. Based on the distinct way JavaScript handles hoisting for different items, I have classified hoisting into three distinct types. Let’s look at each of them with examples:
Function declarations are moved to the top of their scope which means that you can use a function before it is declared in your code.
For example, the following code would work because the function foo()
is hoisted to the top of the scope by the interpreter:
foo();
function foo() {
console.log("Hello, World!");
}
It’s important to note that functions created using function expressions and arrow functions are not hoisted and calling them before declaration will not work. Let’s take a look at an example:
foo(); // ReferenceError: foo is not defined
const foo = function() {
console.log("Hello, World!");
}
Variables declared with var
are also hoisted to the top of their scope however, only the declaration is hoisted, not the initialization. Check it out:
console.log(num); // undefined
var num = 10;
console.log(num); // 10
You’ll get undefined
as the first output and 10
as the second. This is because the variable is hoisted to the top, but without its initialization value, it defaults to undefined
.
Now, let’s talk about hoisting with let and const. There's a common misconception that let
and const
are not hoisted, but that's not true. These two keywords are similar in that they are both hoisted to the top of their scope, just like var
.
However, there's a crucial difference between the two. When you try to access a let
or const
variable before it's been declared, you'll get a ReferenceError: Cannot access 'num' before initialization
. This is because these variables are hoisted without a default initialization, unlike var
.
{
console.log(num); // ReferenceError: Cannot access 'num' before initialization
let num = 10;
console.log(num);
}
This will throw an error and the program will stop executing. This is the so-called “Temporal Dead Zone”, the time during execution when the let
or const
variables are hoisted but not accessible.
One might wonder how the behavior of accessing a variable declared with let
or const
before the initialization differs from accessing an undeclared variable. The difference lies in the error message.
Let’s take an example:
{
console.log(stuff); // ReferenceError: stuff is not defined
console.log(goodStuff); // ReferenceError: Cannot access 'goodStuff' before initialization
let goodStuff = "Something really good";
}
Here, we can observe that the error message for ‘goodStuff’ indicates that it is hoisted and the interpreter recognizes its existence, but it has not yet been initialized. In contrast, the interpreter does not recognize ‘stuff’ as a variable at all. class
declarations are also hoisted the same aslet
and const
with the temporal dead zone.
I hope this article has helped you understand hoisting in JavaScript and how it works with different variable types, functions, and classes. This concept can be tricky, but you can write better and more efficient code by understanding it. Keep practicing and experimenting with code to continue improving your skills. Happy coding!
It’s recommended to steer clear of using var
for variable declarations in JavaScript, as it can result in unpredictable outcomes and confusion during variable handling. Instead, utilizing let
or const
is a good practice.
Also published here.