🧠 JavaScript Hoisting Explained Simply (With Examples)


Introduction to JavaScript Hoisting
JavaScript hoisting is a quirky concept that can easily trip up beginners. It's one of those behaviors in the language that you must see to believe. But once you understand what hoisting is and how it works under the hood, your JavaScript will instantly become more predictable and bug-free.
What Is Hoisting in JavaScript?
Hoisting is JavaScript’s default behavior of moving declarations to the top of their scope—before any code is executed. During the compilation phase, before your code actually runs, the JavaScript engine scans your code for declarations and places them in memory. But there’s a twist: not all declarations behave the same way.
What gets hoisted:
function
declarationsvar
,let
, andconst
variables (but differently)
What doesn't get hoisted:
Function expressions
Arrow functions
Class declarations
Function Declarations and Hoisting
✅ Fully Hoisted With Definitions
When you declare a function using the traditional function
syntax, it's hoisted along with its body. That means you can call it before the line where it's written.
greet(); // ✅ Works
function greet() {
console.log("Hello!");
}
You can safely call greet()
before the function is defined in your code—JavaScript already knows what greet
means during the compilation phase.
Hoisting with var
🤷 Declared, But Initialized as undefined
Variables declared with var
are hoisted, but only the declaration—not the value assignment.
console.log(user); // undefined
var user = "Ujjwal";
Here, user
exists in memory before the code runs, but it’s set to undefined
until the assignment line is reached. This can lead to confusing bugs if you're unaware.
Hoisting with let
and const
⚠️ Hoisted but Uninitialized – Welcome to the TDZ
Variables declared with let
and const
are also hoisted, but they’re not initialized. Trying to access them before the declaration causes a ReferenceError
.
console.log(count); // ❌ ReferenceError
let count = 5;
This period—from the start of the scope to the line where the variable is declared—is called the Temporal Dead Zone (TDZ). It’s JavaScript’s way of saying: “You can’t use this yet.”
Visual Guide to JavaScript Hoisting
Phase | What Happens |
Compilation | All declarations (var, let, const, function) are scanned and stored in memory |
Execution | Code is run line by line, and variable assignments take place |
🔍 Tip: Visualizing this two-phase process makes hoisting much easier to understand.
Understanding Scope in JavaScript
Declaration | Scope Type |
var | Function Scope |
let , const | Block Scope |
function | Function Scope |
Scope defines where in your code a variable can be accessed. Hoisting respects these boundaries. So a let
inside an if
block stays inside that block—even if hoisted.
The Role of Execution Context
Behind the scenes, JavaScript builds an execution context for each function call or script. In the creation phase, it sets up memory space and hoists declarations. Understanding this memory model is key to mastering hoisting.
Common Pitfalls Due to Hoisting
Accessing a
var
variable too early results inundefined
Using
let
orconst
too early throws aReferenceError
Overwriting functions declared later in code can lead to bugs
Best Practices to Avoid Hoisting Issues
Always declare variables and functions at the top of their scope
Use
let
andconst
instead ofvar
for better safetyNever rely on hoisting for program logic
Comparison Table: var vs let vs const vs function
Keyword | Hoisted | Initialized | Scope Type | Notes |
function | ✅ | ✅ | Function | Can be used before declaration |
var | ✅ | ✅ (as undefined ) | Function | Can cause bugs if misused |
let | ✅ | ❌ (TDZ) | Block | Safer than var |
const | ✅ | ❌ (TDZ) | Block | Must be initialized |
When to Use var, let, or const
Use
const
by default—it’s safe and immutableUse
let
when you need to reassignAvoid
var
unless you're dealing with legacy code
Real Examples of Hoisting in Action
function sayHi() {
console.log(greeting); // undefined
var greeting = "Hello";
}
sayHi();
In the example above, greeting
is hoisted, but its assignment isn’t. So the console prints undefined
.
Myths About JavaScript Hoisting
❌ "let and const are not hoisted." → They are, just not initialized!
❌ "Functions always hoist safely." → Only function declarations, not expressions.
❌ "Hoisting is an error." → It's intentional behavior built into the language.
Advanced Concepts: Function Expressions and Arrow Functions
sayHi(); // ❌ TypeError
const sayHi = function() {
console.log("Hi!");
};
This will throw an error. Why? Because sayHi
is a const
variable that’s hoisted but not initialized (TDZ again!).
Frequently Asked Questions (FAQs)
1. Is let
hoisted in JavaScript?
Yes, but it’s not initialized until the line of declaration—this is why accessing it early throws a ReferenceError
.
2. Why is var
considered unsafe?
Because it's hoisted and initialized as undefined
, it can cause unexpected bugs and confusing behavior.
3. Can I use a function before its declaration?
Only if it's declared with function
, not with const
or let
function expressions.
4. What is the Temporal Dead Zone (TDZ)?
The TDZ is the period between entering scope and the actual line of declaration where let
and const
are inaccessible.
5. Does hoisting apply to classes in JavaScript?
Yes, classes are hoisted but not initialized—similar to let
and const
.
6. How can I visualize hoisting?
Think of JavaScript scanning your code first and putting all declarations in memory before it starts executing anything.
Conclusion and Final Thoughts
Hoisting is a fundamental part of JavaScript's execution model. Once you understand how declarations are hoisted during compilation, it becomes much easier to write clean, bug-free code. Stick to let
and const
, declare early, and keep an eye on scope. You'll find that hoisting is less of a mystery—and more of a superpower.
Subscribe to my newsletter
Read articles from Ujjwal Kar directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Ujjwal Kar
Ujjwal Kar
Associate Software Engineer with expertise in Full Stack Development and hands-on experience in executing Data Science projects. Seeking opportunities to apply and enhance knowledge in real-world problems.