Compile Ready
Module 4 · Execution Context & Hoisting

Execution Context

Intermediate10m read8m practice18m total
Execution ContextScopeHoistingRuntime

Introduction

An execution context is the environment JavaScript creates to run a piece of code. The global script gets one context, and every function call gets a fresh one. Each context tracks its variables, lexical scope, this value, arguments, and where execution should continue after a function returns.

This is the mental model behind almost every tricky JavaScript question: why a function can be called before it appears, why var reads as undefined, why let throws in the TDZ, and why recursion can crash with a stack overflow.

Why This Matters

Interviewers ask output-prediction questions to test whether you can simulate an execution context in your head. In production, the same model helps you debug shadowed variables, accidental globals, closure bugs, stack traces, and initialization order in large modules.

Theory

The big idea

An execution context is JavaScript's active record for running code. It answers four questions:

  1. What names exist here? Variables, functions, parameters, classes, and imports are registered as bindings.
  2. Where should name lookup continue? Each context points to an outer lexical environment, forming the scope chain.
  3. What is this? The this binding is established for the current context.
  4. Where does execution resume? A function context remembers the caller so it can return correctly.

The three common context types

ContextWhen it is createdWhat makes it special
Global execution contextOnce, when a script startsHolds top-level declarations and starts the program.
Function execution contextEvery function callHolds parameters, local bindings, arguments for non-arrow functions, and the function's this.
Module execution contextWhen an ES module is evaluatedHas top-level lexical scope and live imports; top-level this is undefined.

Two phases inside every context

  1. Creation / memory phase — the engine prepares the environment: creates bindings, initializes var to undefined, stores function declarations, and leaves let/const/class uninitialized in the temporal dead zone.
  2. Execution phase — the engine runs statements line by line: assignments happen, functions are called, expressions are evaluated, and new contexts are pushed for calls.

Execution context vs lexical environment

People often use the terms together, but they are not identical. The execution context is the whole running frame. Its lexical environment is the structure that maps identifiers to values and points to the outer environment. When a closure survives after a function returns, the stack frame is gone, but the needed lexical environment is kept alive on the heap.

Key interview mantra

JavaScript does not magically move code. It creates bindings first, then executes statements later. Hoisting is the visible behavior produced by that creation phase.

Visual Diagrams

A context is prepared, then executed
Source enters engine
        |
        v
+--------------------------+
|  Creation / memory phase |
|  - create bindings       |
|  - initialize var        |
|  - store functions       |
|  - mark let/const TDZ    |
+-------------+------------+
              |
              v
+--------------------------+
|     Execution phase      |
|  - run line by line      |
|  - assign values         |
|  - call functions        |
|  - return to caller      |
+--------------------------+

The two-phase model is the foundation for hoisting and TDZ behavior.

Contexts form a stack while scopes form a chain
Call stack now

+-----------------------+
| function: inner       |  local bindings
+-----------------------+
| function: outer       |  local bindings
+-----------------------+
| global context        |  global bindings
+-----------------------+

Name lookup from inner: inner environment -> outer environment -> global environment

The call stack controls active execution; the scope chain controls identifier lookup.

Code Examples

A new context for every function call

greet has one function body, but every call gets a separate execution context with its own name parameter and local message binding.

Loading…

Lexical scope is based on where code is written

The function printLabel looks outward to the scope where it was defined, not to the function that happens to call it.

Loading…

Playground

Loading editor…
Console

Press Run to execute the code and see output here.

Output Prediction

Predict the output #1

javascript
1console.log(kind);
2var kind = 'global';
3
4function show() {
5 console.log(kind);
6 var kind = 'local';
7 console.log(kind);
8}
9
10show();
11console.log(kind);

Predict the output #2

javascript
1var label = 'outer';
2
3function first() {
4 var label = 'first';
5 second();
6}
7
8function second() {
9 console.log(label);
10}
11
12first();

Coding Exercises

Create independent counter contexts

Medium

Implement createCounter(start) so each call creates an independent counter object with increment(), decrement(), and value() methods. The exercise is about recognizing that every call to createCounter gets a fresh execution context and a fresh closed-over environment.

Interview Questions

1What is an execution context in JavaScript?

An execution context is the runtime record used to execute code. It contains the lexical environment for identifiers, the variable environment for var declarations, the this binding, function parameters/arguments, and bookkeeping needed to return to the caller. JavaScript creates a global context first and a new function context for every function call. Each context has a creation phase and an execution phase.

Asked at:GoogleMicrosoftAmazon

Follow-ups

  • How does an execution context differ from a lexical environment?
  • What is created during the memory phase?
2Does JavaScript use lexical scope or dynamic scope?

JavaScript uses lexical scope. A function resolves outer variables based on where the function is written, not based on who calls it. The call stack decides which function is currently running, but the scope chain is determined at creation time from the source structure.

Asked at:MetaNetflix

Quiz

1. When is a function execution context created?

2. Which statement best explains hoisting?

Summary

  • An execution context is the runtime environment for running global code, module code, or a function call.
  • Each context has a creation phase and an execution phase.
  • The call stack tracks active contexts; the scope chain controls identifier lookup.
  • Hoisting, TDZ, closures, and stack traces all become easier once you can simulate contexts.

Cheat Sheet

Execution context: runtime frame for code.

Created for: global script/module once; every function call separately.

Contains: lexical environment, variable environment, this, parameters/arguments, return bookkeeping.

Phases: creation/memory first, execution second.

Mantra: bindings first, statements later.