JavaScript Execution Context & Hoisting: Engine Phases & The Call Stack

Everything in JavaScript happens inside an Execution Context. If you aspire to master JavaScript at a senior engineering level or score top marks in university computer science exams, understanding how the V8 engine creates execution contexts and manages the Call Stack is mandatory.

JavaScript Execution Context and Call Stack Architecture

Figure 11: The Two Phases of Execution Context: Memory Creation Phase vs Code Execution Phase, and LIFO Call Stack mechanics.

The Two Types of Execution Context

  • Global Execution Context (GEC): Created automatically as soon as JavaScript starts running. There is only ever ONE Global Execution Context, and it remains at the very bottom of the Call Stack until the browser tab closes.
  • Function Execution Context (FEC): Created afresh each and every time a function is invoked. Pushed onto the Call Stack on call; popped off when the function returns.

The Two Phases of Every Execution Context

Phase 1: Memory Creation Phase (Hoisting)

Before running a single line of executable code, the engine scans the script and allocates memory space for all declarations:

  • Variables declared with var are allocated and assigned undefined.
  • Variables declared with let and const are allocated in the Temporal Dead Zone (TDZ) without initialization.
  • Function Declarations are stored completely in memory with their full body intact.
  • The this keyword is bound.

Phase 2: Code Execution Phase

JavaScript executes the program line-by-line, assigning real values to variables (e.g. score = 95) and invoking functions.

Detailed Code Walkthrough & Call Stack Trace

var x = 10;

function calculateDouble(num) {
    var result = num * 2;
    return result;
}

var y = calculateDouble(x);
console.log(y); // 20
StepCall Stack StateAction Performed
1[Global Execution Context]GEC created. x = undefined, calculateDouble = fn(), y = undefined.
2[Global Execution Context]Line 1: x = 10.
3[FEC: calculateDouble]
[Global Execution Context]
Line 8: calculateDouble(10) invoked. New FEC pushed on top of Call Stack. num = 10, result = undefined.
4[FEC: calculateDouble]
[Global Execution Context]
Line 4: result = 20. Returns 20 to caller.
5[Global Execution Context]FEC popped off stack and garbage-collected. y = 20.
6[Empty Stack]Script ends. GEC popped off.

University Exam Corner (BCA / B.Tech IT)

Exam Question: "What causes a 'Maximum call stack size exceeded' RangeError?"

Answer: Known as a Stack Overflow, this occurs when recursive functions invoke themselves indefinitely without a proper base termination condition. Each recursive call pushes a new Function Execution Context onto the Call Stack until the browser's allocated stack memory limit (typically ~10,000 frames) is breached.

Next Step

How do inner functions remember variables from outer scopes even after the parent function has finished executing? Proceed to: JavaScript Scope Chain & Closures →

Explore Related JavaScript Tutorials

Accelerate your JavaScript mastery by studying these tightly connected core tutorials:

Scope Chain & Closures →

Lexical scopes and closure memory retention.

The this Keyword →

How execution context binds this dynamically.

Event Loop Concurrency →

Call stack frame push/pop lifecycle.

Variable Declarations →

Hoisting differences between var, let, and const.

Share Share on Facebook Share on Twitter Share on LinkedIn Pin on Pinterest Share on Stumbleupon Share on Tumblr Share on Reddit Share on Diggit

You may also like this!