The Bug That Makes Every Beginner Question Reality
I still remember one of the first JavaScript programs that completely confused me.
I wrote this:
console.log(user);
var user = "Aqad";
I expected JavaScript to throw an error.
After all, I was trying to use a variable before creating it.
But the output was:
undefined
Not an error.
Not "Aqad".
Just:
undefined
At first, it felt like JavaScript was cheating.
How could it know that the variable existed before reaching that line?
A few days later, I found another example.
greet();
function greet() {
console.log("Hello Developer");
}
Output:
Hello Developer
Again, JavaScript seemed to be doing something impossible.
The function was called before it was created.
And yet it worked.
This mysterious behavior is called:
Hoisting
And understanding it properly will save you from countless bugs throughout your JavaScript journey.
What Is Hoisting?
The word "hoist" means:
To lift something upward
In JavaScript, hoisting refers to the behavior where variable and function declarations are processed before code execution begins.
Remember the previous chapter?
We learned that JavaScript creates a Memory Creation Phase before execution starts.
That phase is the secret behind hoisting.
The important thing to understand is:
JavaScript does NOT physically move your code.
Many tutorials say:
JavaScript moves variables to the top.
That explanation is convenient, but technically incorrect.
What actually happens is:
JavaScript allocates memory before execution.
Because memory already exists, it looks like variables and functions were moved upward.
Revisiting Execution Context
Let's connect hoisting with what we learned earlier.
Consider:
var city = "Dubai";
Before execution begins:
JavaScript enters the Memory Creation Phase.
Memory becomes:
city → undefined
Then execution starts.
city = "Dubai";
Memory updates:
city → Dubai
Because the variable already exists in memory, JavaScript allows access to it before assignment.
This behavior creates hoisting.
Understanding Hoisting Through a Hotel Analogy
Imagine you book a hotel room online.
Before you arrive:
Your room number is reserved.
Your details are registered.
Your booking exists in the system.
However:
The room may not be fully prepared yet.
When you arrive, the reservation exists, but everything may not be ready.
Variables declared with var work similarly.
JavaScript reserves memory before execution.
The value arrives later.
Hoisting with var
Example:
console.log(user);
var user = "Aqad";
Let's see what happens internally.
Memory Creation Phase
JavaScript scans the code.
Memory:
user → undefined
Execution Phase
Line 1:
console.log(user);
Output:
undefined
Because memory exists but no value has been assigned.
Line 2:
user = "Aqad";
Memory becomes:
user → Aqad
Program finishes.
Visualizing the Process
Code:
console.log(user);
var user = "Aqad";
Memory Phase:
user → undefined
Execution:
Print user
↓
undefined
↓
Assign Aqad
This explains the strange output.
Hoisting with Functions
Functions behave differently.
Consider:
greet();
function greet() {
console.log("Hello");
}
Output:
Hello
Why?
Because during memory creation:
greet → complete function definition
Unlike variables, JavaScript stores the entire function immediately.
Memory Creation for Functions
Code:
function greet() {
console.log("Hello");
}
Memory:
greet → function() {
console.log("Hello");
}
The entire function is available before execution starts.
That is why calling it earlier works perfectly.
Why Function Hoisting Feels Different
Compare:
Variable:
console.log(user);
var user = "Aqad";
Output:
undefined
Function:
greet();
function greet() {
console.log("Hello");
}
Output:
Hello
Difference:
Variables get:
undefined
Functions get:
Complete function definition
This difference is extremely important.
Many interview questions are based on it.
Enter let and const
When JavaScript was first created, developers mainly used:
var
Over time, large applications became harder to maintain.
Unexpected bugs appeared.
To solve these problems, ES6 introduced:
let
const
These behave differently from var.
Example Using let
console.log(name);
let name = "Aqad";
Output:
ReferenceError
Many beginners get confused here.
If hoisting exists, why doesn't this work?
The answer lies in something called the Temporal Dead Zone.
Understanding the Temporal Dead Zone (TDZ)
The name sounds scary.
But the idea is simple.
Imagine a cinema ticket.
You purchase it online.
The ticket exists.
However, you cannot enter the theater before the show starts.
There is a waiting period.
Similarly:
Variables declared with let and const are created during memory allocation.
But they remain inaccessible until their declaration line executes.
This inaccessible period is called:
Temporal Dead Zone
or simply:
TDZ
Visualizing TDZ
Code:
console.log(name);
let name = "Aqad";
Memory Phase:
name → reserved
Execution:
Line 1:
console.log(name);
JavaScript says:
Access denied
Result:
ReferenceError
Only after reaching:
let name = "Aqad";
does the variable become usable.
Why TDZ Was Introduced
JavaScript developers learned from years of bugs caused by var.
Consider:
if (true) {
var user = "Aqad";
}
Outside:
console.log(user);
Output:
Aqad
Many developers expected the variable to stay inside the block.
Instead, it leaked outside.
This caused serious problems in large projects.
let and const were introduced to prevent such mistakes.
The TDZ is part of that protection mechanism.
Hoisting with const
Example:
console.log(country);
const country = "India";
Output:
ReferenceError
Same reason:
Temporal Dead Zone.
Real World Example: Login System
Imagine an authentication application.
console.log(isLoggedIn);
let isLoggedIn = true;
If JavaScript silently returned:
undefined
developers might accidentally introduce security bugs.
By throwing an error immediately:
ReferenceError
JavaScript helps developers detect mistakes earlier.
Function Expressions and Hoisting
Now let's look at a tricky situation.
Consider:
greet();
var greet = function() {
console.log("Hello");
};
What happens?
Many beginners expect: Hello
But the output is: TypeError
Why? Let's analyze.
Memory Phase
JavaScript sees:
var greet
Memory becomes:
greet → undefined
Notice:
The function itself is NOT stored.
Only the variable is created.
Execution Phase
Line 1: greet();
Current value: undefined
JavaScript tries to execute:
undefined()
Which is impossible.
Result:
TypeError
This is one of the most common interview questions.
Function Declaration vs Function Expression
Function Declaration
function greet() {
console.log("Hello");
}
Fully hoisted.
Can be called before definition.
Function Expression
var greet = function() {
console.log("Hello");
};
Only variable is hoisted.
Function is not available until assignment.
Common Interview Question
What is the output?
console.log(a);
var a = 10;
Answer:
undefined
What is the output?
console.log(a);
let a = 10;
Answer:
ReferenceError
What is the output?
greet();
function greet() {
console.log("Hello");
}
Answer:
Hello
What is the output?
greet();
var greet = function() {
console.log("Hello");
};
Answer:
TypeError
Understanding WHY these outputs occur is more important than memorizing them.
A Developer's Rule of Thumb
Can you rely on hoisting?
Technically yes.
Should you rely on hoisting?
No.
Professional developers usually write:
const user = "Aqad";
console.log(user);
instead of:
console.log(user);
var user = "Aqad";
Readable code is always better than clever code.
Future developers—including your future self—will thank you.
How Modern Teams Write JavaScript
In most modern projects:
Prefer
constUse
letwhen values changeAvoid
varDeclare variables before using them
Declare functions clearly
This eliminates many hoisting-related bugs.
Why Understanding Hoisting Matters
Hoisting is not just an interview topic.
It helps explain:
Why some variables return
undefinedWhy others throw errors
Why function declarations behave differently
Why
letandconstwere introducedHow JavaScript prepares memory before execution
Most importantly:
Hoisting reveals that JavaScript is doing much more behind the scenes than we can see.
Summary
In this chapter, we learned:
What hoisting is
How memory creation causes hoisting
Hoisting with
varHoisting with functions
Hoisting with
letHoisting with
constTemporal Dead Zone (TDZ)
Function declarations vs function expressions
Common interview questions
Modern best practices
Think of hoisting as JavaScript's preparation phase.
Before the show begins, JavaScript sets the stage, reserves seats, and prepares resources.
Some resources become available immediately.
Others remain locked until the right moment.
Understanding that difference is the key to mastering hoisting.
And now that we know how JavaScript prepares variables and functions, it's time to understand where those variables actually live.
Because the next topic explains why some variables are visible everywhere while others seem to disappear.

0 Comments