Hoisting is a JavaScript mechanism where variable and function declarations are moved to the top of their containing scope during the compilation phase, before the code is executed. This means that you can use variables and functions before they are declared in the code.
When JavaScript code runs, it’s not executed line by line immediately.
The JS engine (like V8 in Chrome or Node.js) first performs two phases:
- The engine scans the code before running it.
- It creates something called a variable environment for each scope.
-
During this creation phase, it:
- Registers all variable and function declarations
- Sets up memory bindings for them inside that scope
Execution phase — actually runs the code line by line
Hoisting happens during the creation phase, before any code executes.
// Creation Phase (before execution)
Memory Environment:
a → undefined // var declaration found
// Execution Phase
console.log(a); // reads 'undefined'
a = 10; // assigns new value
TDZ is the period between the start of a scope and the point where a let or const variable is initialized.
How it differs by declaration type
| Declaration | Hoisted? | Initialization timing | Accessible before initialization? |
|---|---|---|---|
var |
Yes | Set to undefined at compile time |
Yes, returns undefined
|
let |
Yes (binding created) | Initialized only when execution reaches it | No — in Temporal Dead Zone |
const |
Yes (binding created) | Must be initialized at declaration | No — in Temporal Dead Zone |
function |
Yes (entire function stored in memory) | Immediately available | Yes |
Example
console.log(x); // undefined
console.log(y); // ReferenceError
console.log(z); // ReferenceError
var x = 5;
let y = 6;
const z = 7;
foo(); // Works
function foo() {
console.log("Hoisted function!");
}
What the engine actually does internally
Before code runs:
1. Create Global Execution Context (GEC)
2. Create Global Lexical Environment:
- Environment Record (variable bindings)
- Outer Environment Reference (null)
Visual — Execution Context Lifecycle
Global Execution Context
│
├─ Creation Phase
│ ├─ Allocate memory for variables and functions
│ ├─ var → undefined
│ ├─ let/const → TDZ
│ └─ function → full object in memory
│
└─ Execution Phase
├─ Assign actual values
├─ Execute statements line by line
└─ Create new Execution Contexts for functions
Top comments (0)