Execution Context

⭐ Interview Importance: HIGH
⏱️ Revision Time: 4 min

TL;DR

The Execution Context is the abstract environment created by the JavaScript engine when it runs code. It contains the code currently running, and everything that aids in its execution (variables, the this keyword, and references to outer scopes).

Mental Model

How It Works

There are two main types of Execution Contexts:

  1. Global Execution Context (GEC): The default context created when your script starts. It creates the global object (window in browsers, global in Node) and sets this to point to it.
  2. Function Execution Context (FEC): Created brand new every single time a function is called.

The Two Phases of Creation:
Whenever an Execution Context is pushed to the Call Stack, it undergoes two phases:

  1. Creation Phase:
    • Scans the code.
    • Sets up the Memory space for variables and functions (Hoisting).
    • Determines the value of this.
    • Creates the Scope Chain connection.
  2. Execution Phase:
    • Executes the code line by line.
    • Assigns actual values to the variables in memory.

Example

var name = "Global";

function outer(msg) {
  var prefix = "Log:";
  
  // A new context is created here!
  function inner() {
      console.log(prefix, msg, name);
  }
  
  inner();
}

// A new context is created here!
outer("Hello");

What the engine sees during inner()’s Execution Context:

  1. Local Variables: None.
  2. this Binding: window (or undefined in strict mode).
  3. Outer Reference: Points to outer()’s context.
    When inner() tries to log prefix, it looks in its own context, doesn’t find it, uses the Outer Reference to look in outer(), finds prefix, and then does the same for name looking all the way up to the Global Context.

Common Output Question

console.log(a);
var a = 5;
console.log(b);
let b = 10;

Q: What happens based on the phases of the Execution Context?
A: During the Creation Phase, a is stored in memory as undefined, and b is stored in the Temporal Dead Zone (TDZ). During the Execution Phase, the first line executes and prints undefined. Then a is assigned 5. The third line executes, and because b is still in the TDZ, it throws a ReferenceError: Cannot access 'b' before initialization.

Senior Interview Question

Q: How does the Execution Context relate to Closures?

A: When a function finishes executing, its Function Execution Context is popped off the Call Stack and normally destroyed by the Garbage Collector. However, if that function returns an inner function, the inner function maintains a hidden reference ([[Environment]]) to the Variable Environment of the parent’s Execution Context. This prevents the Garbage Collector from sweeping those variables, keeping them alive in memory. This specific preservation of a dead context’s variable environment is exactly what a Closure is.