What is Hoisting in JavaScript? (Explained with Execution Context)

Have you ever experienced a moment where your JavaScript code somehow works even though you referenced a variable or called a function before actually declaring it?

console.log(name); // undefined but not an error
var name = "Gopi";

This isn't some bug or random behaviour. It’s not mysterious — it’s the result of the exceptional design of the JavaScript engine and how it handles code execution through well-defined conceptual steps.

This behaviour is called Hoisting

And to truly understand hoisting, we need to dive into the Execution Context — the foundation of how JavaScript runs your code.

How JavaScript Executes Code (The Real Reason Behind Hoisting)

When JavaScript runs, it creates something called an Execution Context , a behind-the-scenes environment where JavaScript code lives during execution.

When JavaScript runs, it creates something called an Execution Context — a behind-the-scenes environment where your code lives during execution.

Each time a script or function runs, this context is built in two phases:

  1. Memory Creation Phase (Also known as Hoisting Phase)

  • JavaScript scans your code from top to bottom and allocates memory for:

    • Variables declared with var → initialised as undefined

    • Functions → fully stored

  1. Code Execution Phase (Also known as Thread Phase )

  • JavaScript runs your code line by line, assigning values and invoking functions.

Example 1:

Example 2:

Example 3:

At the start of execution js engine read the js file and initialise all the variables with undefined and functions with the whole function. This is what is called Hoisting. And for this, we think that js can access the variables before its declaration.( For deep diving into it, I suggest to use the debug mode in vs code js debugging terminal )

Then in the execution phase, line by line execution starts . For a var , variable is accessed anywhere. But for let and const , there is a concept called TDZ (Temporal Dead Zone). That means variables are initialised with undefined, but is only accessible after the declaration of the variable. Above the variable declaration, that part is called the Temporal Dead Zone of the variable.

And for functions, while executing , it creates its own execution context and after completion of execution, the execution context of the function is erased. And one thing is also notable,

func();//Error here as cannot call undefined()
var func = function(){
    console.log("Hello")
} // func variable is given a reference of a function. It was not a funtion at first

In this case, func is a var variable, it is first initialised with undefined. So calling undefined gives an error.

Best Practices

  • Use let and const instead of var

  • Always declare variables at the top of their scope

  • Never rely on hoisting — it’s better to write code in a predictable order

So the next time JavaScript seems to "magically" run your function or access a variable before it's written, remember, it’s not a mystery. It’s the intentional, conceptual design of how JavaScript works.

If this helped you understand hoisting better, share it with a fellow developer!

10
Subscribe to my newsletter

Read articles from Gopikanta Mondal directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Gopikanta Mondal
Gopikanta Mondal