Execution Context and the Call Stack

Jul 22, 2025

Understanding JavaScript Execution Context and the Call Stack

JavaScript’s behind-the-scenes mechanics can seem tricky, but understanding Execution Context and the Call Stack is like getting a map to navigate how your code runs. In this post, we’ll break down these core concepts, explore how they work together, and walk through a clear example to make it all click.

What is an Execution Context?

An Execution Context is an abstract concept of an environment where JavaScript code is evaluated and executed. Every line of code runs inside one of these contexts, which acts like a container with two key parts:

  • Memory Component (Variable Environment): Assigns memory to variables and functions.
  • Code Component (Thread of Execution): Runs the code line by line.

Each execution context forms in two phases: the Memory Creation Phase and the Code Execution Phase.

Memory Creation Phase

In this phase, the JavaScript engine allocates memory for all variables and functions in the current context. Variables are assigned undefined as a placeholder, while functions store their entire code. This is stored as key-value pairs.

For example, take this code:

var name = "JavaScript";
function greet(param) {
  console.log(`I love ${param}`);
}

The engine sets up:

  • name: undefined
  • greet: [function code]

Code Execution Phase

Here, the engine executes the code line by line. JavaScript is synchronous and single-threaded, meaning it handles one task at a time, moving to the next line only after the current one finishes. During this phase:

  • Variables get their actual values (e.g., name becomes "JavaScript").
  • When a function call is encountered, it creates a new execution context for it.

The Call Stack

The Call Stack is a data structure that follows the LIFO (Last In, First Out) principle, like stacking books, where the last one added is the first removed. It tracks the order of execution of execution contexts in JavaScript.

Here’s the flow:

  1. The Global Execution Context is created when a script starts and pushed onto the Call Stack.
  2. A function call creates a new execution context, which is pushed onto the stack.
  3. When the function finishes, its context is popped off.
  4. After all code runs, the Global Execution Context is popped off.
ℹ️

The Call Stack maintains the order of execution of Execution Contexts.

Example: Step-by-Step Execution

Let’s analyze this code to see the Execution Context and Call Stack in action:

var name = "JavaScript";

function greet(param) {
  console.log(`I love ${param}`);
}

greet(name);

Step-by-Step Breakdown

  1. Global Execution Context Created:

    • The JavaScript engine creates the Global Execution Context and pushes it onto the Call Stack.
    • Memory Creation Phase:
      • name is allocated memory and set to undefined.
      • greet is allocated memory and stores the entire function code.
    • Code Execution Phase:
      • The engine assigns "JavaScript" to name, replacing undefined.
      • The engine encounters the greet function call and creates a new execution context for it.
  2. Function Call greet:

    • When greet(name) is encountered, a new execution context for greet is created and pushed onto the Call Stack.
    • Memory Creation Phase (for greet):
      • The parameter param is allocated memory and assigned the placeholder value undefined.
    • Code Execution Phase (for greet):
      • The engine assigns "JavaScript" to param variable, replacing undefined.
      • The engine executes console.log("I love JavaScript") and I love JavaScript is logged on the console.
  3. Function Completion:

    • After greet finishes, its execution context is popped off the Call Stack.
    • Control returns to the Global Execution Context.
  4. Global Completion:

    • With no more code to execute, the Global Execution Context is popped off the Call Stack, leaving it empty.

Conclusion

Grasping the Execution Context and Call Stack is key to debugging and understanding how JavaScript processes your code. It sets the stage for diving into advanced topics like closures, async functions, and the event loop.

Hope this breakdown helps you see how JavaScript manages code execution! If you have any questions feel free to reach out to me on LinkedIn.

Manak Upadhyay