Execution Context & Call Stack
20 min read
Execution ContextCall StackLIFOCreation PhaseStack OverflowDevTools Debugging
How JavaScript Tracks What's Running
Every time JavaScript runs code, it creates an Execution Context — a wrapper around the currently executing code that tracks variables, the scope chain, and the value of this.
Types of Execution Contexts
| Type | Created When | Contains |
|---|---|---|
| Global EC | Script loads | Global variables, window/globalThis |
| Function EC | Function is called | Local variables, arguments, this |
| Eval EC | eval() runs | Dynamic scope (avoid!) |
The Call Stack (LIFO)
The Call Stack is a data structure that records where in the program we are. When a function is called, it's pushed onto the stack. When it returns, it's popped off.
function third() { console.log("3rd"); }
function second() { third(); console.log("2nd"); }
function first() { second(); console.log("1st"); }
first();
// Call Stack: [global] → [first] → [second] → [third]
// Output: 3rd, 2nd, 1stStack Overflow
If the call stack exceeds its limit (typically ~10,000–15,000 frames), you get a RangeError: Maximum call stack size exceeded.
// ❌ Infinite recursion = stack overflow
function infinite() { infinite(); }
infinite(); // RangeError!Creation Phase vs Execution Phase
Each execution context goes through two phases:
- Creation Phase: Memory allocated for variables (
undefinedforvar, uninitialized forlet/const), functions hoisted entirely. - Execution Phase: Code runs line-by-line, variables get assigned.
console.log(a); // undefined (var is hoisted)
console.log(b); // ReferenceError (TDZ for let)
var a = 10;
let b = 20;Visualizing with Chrome DevTools
Open DevTools → Sources → Set breakpoints → Watch the Call Stack panel on the right. This shows exactly which functions are stacked.