Touching the Heart of JavaScript Hoisting

Nitish Kumar Singh
Jun 1, 2025Have you ever seen JavaScript code work even when things are used before they are written? That’s not magic — it’s hoisting. In this blog, we’ll learn what hoisting means and how it works in a very simple way.
We’ll explore how hoisting affects variables, functions, and classes in JavaScript. We’ll see which things can be used before they are written and which ones cause errors. We’ll also look at real examples to make things clear.
What Is Hoisting?
Hoisting is a behavior in JavaScript where declarations are moved to the top of its scope before the code runs. This means variables and functions can be used before we write them in our code.
Take a look at the code below.
console.log(name); // undefined
var name = "Nitish";
In the above code, the variable name
is used before it is written. JavaScript moves the var name
; part to the top, so the code becomes like this:
var name;
console.log(name); // undefined
name = "Nitish";
That’s why it doesn’t give an error but prints undefined
, and this behavior of JavaScript is known as hoisting.
Hoisting is a special feature found only in JavaScript. Other languages don’t allow using variables or functions before declaring them. JavaScript does this in two steps: first it scans the code (Creation phase), then it runs it (Execution phase).
Types of Hoisting
Hoisting doesn’t work the same way for everything in JavaScript. It behaves differently with variables
, functions
, classes
and imports
. We will look at each one and see how hoisting works in simple examples.
Value Hoisting
Value hoisting means able to use the variables' value before the line they are declared. This only happens with function
declarations. We can call the function even before its code appears in the file.
This is an example of Value Hoisting:
greet(); // Hello Nitish
function greet() {
console.log("Hello Nitish");
}
In this example, the full function (name and its block) is moved to the top by JavaScript. That’s why we can call greet()
even before the function is declared. This is called Value Hoisting.
Declaration Hoisting
Declaration hoisting means only the name of the variable is moved to the top, not its value. This happens with var
. So if we use the variable before the value is set, it gives undefined
instead of an error.
Below code is an example of it:
console.log(age); // undefined
var age = 25;
Here, only the var age;
part is hoisted, not the value 25
. So when we try to print age before its value is set, it shows undefined
.
Lexical Hoisting
In this hoisting, the declaration of the variable causes behavior changes in its scope before the line in which it is declared. I use the term lexical hoisting here just for naming the heading, as it appears only with lexical declarations.
Declarations with let
, const
, and class
are hoisted with this type but not initialized. They stay in a TDZ (temporal dead zone) until the code reaches their line. Using them before declaration causes an error.
We can clearly understand with the code example below:
const x = 1;
{
console.log(x); // ReferenceError
const x = 2;
}
Inside the block, const x = 2
is hoisted but not initialized. So when we try to console.log(x)
, it causes a ReferenceError
because x
is in the TDZ until the declaration line. Here, JavaScript’s behavior changes and it no longer accesses the outer variable because of the inner const x = 2
.
Side Effects Hoisting
In this hoisting, the side effects of a declaration are produced before running the rest of the code that contains it, and it is basically found with imports
.
We can see side effect and value hoisting with imports and understand them with the code below:
// File1 code
export class Greet{
sayHello = ()=>{
console.log("Hello Nitish");
}
}
console.log("Hello Nitish in File1");
// File2 code
new Greet().sayHello();
import { Greet } from "./File1.js";
/*
Output
Hello Nitish in File1 // Due to side effect hoisting
Hello Nitish // Due to Value hoisting
*/
In the above code, we have imported a class from file1 then that file1's code will run before the rest of fil2 code runs, even if we haven’t used the imported class yet. And we are using the class before its declaration, which works because it's an imported class. Otherwise, it would throw an error due to lexical hoisting.
Where Hoisting Happens
Hoisting happens with different types of declarations in JavaScript. It works with var
, let
, const
, function
, class
, and import
. But the way hoisting works is not the same for all. We have already seen that which type of hoisting found with which type of declarations.
Now let’s quickly look at the summary of hoisting types and where they are found. This will help us remember how each type behaves and which declarations follow them.
- Value Hoisting: This is full hoisting found in
function
declarations. Both the name and the full function body are hoisted, so you can call them before they appear in code. - Declaration Hoisting: Found in
var
and the variable name is hoisted, but its value is set to undefined until the assignment runs. - Lexical Hoisting: Found in
let
,const
, andclass
. The name is hoisted but not initialized. Accessing them early causes aReferenceError
due to the temporal dead zone. - Import Hoisting: Found in
import
and it is hoisted and module code runs before anything else.
So this is what JavaScript hoisting is — how it handles our code behind the scenes. We saw how it works with functions, var
, let
, const
, class
, and import
. Knowing these types helps us write better code and avoid unexpected errors.
I hope you enjoyed learning about hoisting with me, understood the logic clearly, discovered how JavaScript handles things behind the scenes, and found this post helpful.
Thanks for reading! 🤝 Happy Coding! ✨