Ticker

6/recent/ticker-posts

Chapter 10: Hoisting — Why JavaScript Sometimes Behaves Like Magic

Chapter 10: Hoisting — Why JavaScript Sometimes Behaves Like Magic


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 const

  • Use let when values change

  • Avoid var

  • Declare 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 undefined

  • Why others throw errors

  • Why function declarations behave differently

  • Why let and const were introduced

  • How 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 var

  • Hoisting with functions

  • Hoisting with let

  • Hoisting with const

  • Temporal 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.

Post a Comment

0 Comments