DEV Community

Cover image for How Hoisting works internally?
Jyoti chaudhary
Jyoti chaudhary

Posted on

How Hoisting works internally?

πŸ”ΉWhat is Hoisting?

Hoisting is JavaScript's default behavior of moving declarations to the top of their scope during the memory creation phase, before code execution.

πŸ”ΉHow Hoisting Works Internally

JS code runs in two phases:

1. Memory Creation Phase (Hoisting happens here)

During the memory creation phase, JavaScript parses the code and allocates memory for variable and function declarations, storing them inside the execution context before code execution begins.

Or

In simple terms, JavaScript scans the code and then allocates memory for variables, functions etc and then stores them in memory.

  • JS scans the code

  • Allocates memory for:

    • Variables
    • Functions
  • Stores them in memory

2. Execution Phase

  • Code runs line by line

  • Assignments happen

  • Functions are executed


πŸ”ΉTypes of Hoisting in JavaScript

  • var hoisting

  • let hoisting

  • const hoisting

  • Function declaration hoisting

  • Function expression hoisting

  • Class hoisting

1. var Hoisting (Fully Hoisted)

console.log(a);
var a = 10;

Internal:
var a; // undefined
Enter fullscreen mode Exit fullscreen mode

βœ” Declaration is hoisted
βœ” Initialized with undefined


2. let and const Hoisting (Hoisted but NOT initialized)

console.log(b);
let b = 20;

Error:
ReferenceError: Cannot access 'b' before initialization

---

console.log(c);
const c = 30;
❌ Error:

ReferenceError: Cannot access 'c' before initialization
Enter fullscreen mode Exit fullscreen mode

let and const is hoisted, But placed in Temporal Dead Zone (TDZ)

πŸ”₯ Temporal Dead Zone (TDZ)
TDZ = time between: entering scope and variable initialization

// TDZ starts
console.log(b); // ❌ error
let b = 20;
// TDZ ends
Enter fullscreen mode Exit fullscreen mode

let is hoisted but not initialized, and accessing it before declaration causes a ReferenceError due to TDZ.


3. Function Declaration Hoisting (Fully Hoisted)

sayHello();

function sayHello() {
  console.log("Hello!");
}

Internally:
sayHello β†’ function reference
Enter fullscreen mode Exit fullscreen mode

4. Function Expression Hoisting

sayHi();

var sayHi = function () {
  console.log("Hi");
};

TypeError: sayHi is not a function
Enter fullscreen mode Exit fullscreen mode

Why?
-> sayHi is hoisted as undefined
-> Calling undefined() ❌

sayHi();
const sayHi = function () {
  console.log("Hi");
};

ReferenceError (TDZ)
Enter fullscreen mode Exit fullscreen mode

Only function declarations are fully hoisted, not function expressions.


πŸ”ΉExecution Context

When JavaScript runs your code, it does not execute it line by line immediately.

It does two phases for every execution context:

  1. Memory Creation Phase (also called Creation / Hoisting phase)
  2. Execution Phase

What is an Execution Context?

Execution Context = an environment where JavaScript code is evaluated and executed

Think of it like a box created by JS to run code.

Each execution context contains two main things:

  1. Memory (Variable Environment) β‡’ Variables + Functions stored here
  2. Code (Thread of Execution) β‡’ Code executes line by line

πŸ‘‰ Types of Execution Context

  1. Global Execution Context (GEC)
    – Created when the program starts
    – Only one

  2. Function Execution Context (FEC)
    – Created each time a function is called


πŸ‘‰ Memory Component Stores

During memory creation phase:

  • Variables
  • Function declarations
  • Function parameters
  • Scope references

πŸ‘‰ Where This Memory Lives Physically?

Stack = where execution happens
Heap = where data lives

Heap Memory
  • Large and unstructured
  • Stores:
    • Objects
    • Functions
    • Closures
    • Complex data
Stack Memory
  • Fast and LIFO ordered
  • Stores:
    • Execution contexts
    • Primitive values (often)
    • References (addresses) to heap

πŸ‘‰ Who Gives This Memory?

JavaScript Engine

Examples:

  • V8 (Chrome, Node.js)
  • SpiderMonkey (Firefox)
  • JavaScriptCore (Safari)
The JS Engine:
  • Allocates memory
  • Manages memory
  • Frees memory (Garbage Collection)

πŸ”Ή Internally What Happens?

When JS runs:

Step 1 β†’ Engine creates Execution Context
Step 2 β†’ Allocates memory for variables/functions
Step 3 β†’ Runs code

πŸ”₯ Real Flow
Browser / Node
   ↓
JavaScriptEngine(V8 etc.)
   ↓
Creates Execution Context
   ↓
AllocatesMemory(Hoisting Phase)
   ↓
Executes Code
Enter fullscreen mode Exit fullscreen mode
Example:
var a = 10;
let b = 20;
const c = 30;

function add(x, y) {
  var sum = x + y;
  return sum;
}

let result = add(2, 3);
Enter fullscreen mode Exit fullscreen mode

STEP 1. Global Execution Context (GEC) is created

  • GEC is pushed into the CALL STACK
  • Memory Creation Phase (inside GEC)

πŸ”ΉWhat goes to STACK memory?

Primitive variables
var a;
let b;
const c;
let result;
Enter fullscreen mode Exit fullscreen mode

Stored in stack memory (inside GEC):

a      β†’ undefined
b      β†’<uninitialized>
c      β†’<uninitialized>
result β†’<uninitialized>
Enter fullscreen mode Exit fullscreen mode

πŸ”Ή What goes to HEAP memory?

Function declaration
functionadd(x, y) { ... }

Enter fullscreen mode Exit fullscreen mode
  • Function object is stored in heap
  • Stack stores reference (address) to it
STACK (GEC)           HEAP
─────────────        ─────────────
add  β†’0x123  ───▢function add(){...}
Enter fullscreen mode Exit fullscreen mode

STEP 2: Execution Phase starts

All primitives β†’ stored directly in STACK

STACK
a β†’10
b β†’20
c β†’30
Enter fullscreen mode Exit fullscreen mode

STEP 3: Function call happens

let result =add(2,3);
Enter fullscreen mode Exit fullscreen mode

πŸ”ΉWhat happens internally?

  • New Function Execution Context (FEC) created

  • Pushed into CALL STACK

CALL STACK
────────────
|  FEC(add)|
|    GEC|
────────────
Enter fullscreen mode Exit fullscreen mode

πŸ”Ή Function Execution Context Memory
Parameters & local variables
x =2
y =3
sum =undefined
Enter fullscreen mode Exit fullscreen mode

All are primitives β†’ STACK

STACK (FEC)
x   β†’2
y   β†’3
sum β†’ undefined
Enter fullscreen mode Exit fullscreen mode
Execution inside function
sum = x + y;// 5
return sum;
Enter fullscreen mode Exit fullscreen mode
  • sum becomes 5
  • Value returned to global context
Function ends

❌ Function Execution Context is popped from stack

CALL STACK
──────────
|  GEC   |
──────────

Enter fullscreen mode Exit fullscreen mode
Returned value assigned:
result β†’ 5   (STACK)
Enter fullscreen mode Exit fullscreen mode

Top comments (0)