LESSON 02 · BEGINNER4 min read

Execution Contexts: Global, Function, and Lexical Environments

Demystify execution contexts. Learn how Variable Environments, Lexical Environments, and the Creation Phase prepare your code for execution.

ES2024 / Node.js 20+Free to readModule 1 of 10
YOUR NEXT SMALL WINS

By the end, you’ll be able to…

  • Distinguish between the Global Execution Context and Function Execution Contexts.
  • Break down the two-phase lifecycle: Creation Phase versus Execution Phase.
  • Map how Variable Environments and Lexical Environments manage identifier bindings.

01What is an Execution Context?

An Execution Context is an abstract conceptual environment created by the JavaScript engine to evaluate and execute code. Think of it as a protective capsule containing everything required to execute a specific block of code: the exact memory allocated for variables and functions, the scope chain reference to outer environments, and the binding value of the this keyword.

There are two primary types of execution contexts you interact with on a daily basis: the Global Execution Context (GEC) and Function Execution Contexts (FEC). The GEC is born the moment your script starts. It is unique: there is only ever one global context in an execution environment. It creates the global object (window in browser tabs, global in Node.js) and sets this to reference that global object. Whenever a function is invoked, a brand new Function Execution Context is created and pushed onto the call stack.

example.js⚡JavaScript
Ctrl + ↵
Output
Click Run or press Ctrl+Enter
Output will appear here after you run the code.

02The Two Phases: Creation Phase vs. Execution Phase

Whenever an execution context is spun up, the engine does not immediately execute the code line by line. Instead, it processes the context in two distinct chronological phases: the Creation Phase and the Execution Phase.

During the Creation Phase, the engine scans the code without executing statements. It performs variable and function registration: it binds function declarations into memory with their full definitions, reserves space for var variables and initializes them to undefined, and registers let and const variables in an uninitialized state. It also constructs the scope chain and resolves this. Only after the Creation Phase is complete does the engine enter the Execution Phase, running statements sequentially from top to bottom, executing expressions, and assigning concrete runtime values to variables.

example.js⚡JavaScript
Ctrl + ↵
Output
Click Run or press Ctrl+Enter
Output will appear here after you run the code.

03Variable Environment vs. Lexical Environment

Internally, ECMAScript specifications define that an execution context holds two closely related environment records: the VariableEnvironment and the LexicalEnvironment.

The VariableEnvironment holds bindings declared with legacy var statements within the function or global scope. In contrast, the LexicalEnvironment holds modern block-scoped declarations made with let, const, class, and function declarations within blocks. Because blocks (such as if blocks or for loops) create their own sub-lexical environments while sharing the enclosing variable environment, JavaScript is able to cleanly isolate block-scoped variables without polluting outer function scopes.

example.js⚡JavaScript
Ctrl + ↵
Output
Click Run or press Ctrl+Enter
Output will appear here after you run the code.

04Why This Matters in Production

Bugs in production frequently stem from a misunderstanding of how the creation phase handles initialization. Developers inspecting stack traces or debugging intermittent undefined variable references are often victim to assumptions about line-by-line execution order.

By internalizing the two-phase lifecycle of execution contexts, you can instantly explain why variables behave differently before their declaration lines, structure modules cleanly to avoid temporal initialization bugs, and write predictable code across asynchronous boundaries.

LET IT CLICK

The ideas worth keeping.

  • Execution contexts manage variable memory, scope chains, and 'this' bindings.
  • The context lifecycle has two phases: Creation (memory allocation) and Execution (evaluation).
  • Block statements isolate let/const bindings inside ephemeral child Lexical Environments.
TURN UNDERSTANDING INTO SOMETHING YOU CAN DO

Make it yours.

Type and test your code right here in the interactive workspace. Run your solution, check the output, and compare with the worked guide when ready.

01

Exercise 1: Tracing Execution Context Stack

Write a short script with nested functions and return an array representing the exact order of function context names pushed onto the call stack during execution.

your_turn_1.js⚡JavaScript
Ctrl + ↵
Output
Click Run or press Ctrl+Enter
Output will appear here after you run the code.
Explore a worked solution
one_possible_solution.jsJavaScript
function traceStack() {  const stack = ['global'];  function first() {    stack.push('first');    second();  }  function second() {    stack.push('second');  }  first();  return stack;}// Returns: ['global', 'first', 'second']

When first() is called, its execution context is created and pushed onto the stack. When it calls second(), second's context is pushed on top.

02

Exercise 2: Block Scope Isolation Guard

Write a function that demonstrates how let prevents leakage outside of a loop while var would inadvertently leak into the outer context.

your_turn_2.js⚡JavaScript
Ctrl + ↵
Output
Click Run or press Ctrl+Enter
Output will appear here after you run the code.
Explore a worked solution
one_possible_solution.jsJavaScript
function testScopeLeak() {  for (let i = 0; i < 3; i++) {    // i is isolated to each loop iteration's Lexical Environment  }  try {    return i;  } catch (err) {    return 'Correctly isolated: i is not accessible outside the loop';  }}

Because let is scoped to the loop's LexicalEnvironment, referencing i outside the loop throws a ReferenceError, proving clean isolation.

A SMALL QUESTION. A USEFUL NEXT STEP.

What stayed with you?

Check the ideas while they’re fresh. Your answers stay in this page and feedback appears as you go.

A LITTLE ACTIVE RECALL0 / 3 answered
01What occurs during the Creation Phase of an Execution Context?
02How does a block statement (such as an if statement) interact with Lexical Environments?
03How many Global Execution Contexts exist within a single JavaScript runtime instance?
⚡CODING CHALLENGE
🔒Required to Mark Lesson Complete

Exercise 1: Tracing Execution Context Stack

Write a short script with nested functions and return an array representing the exact order of function context names pushed onto the call stack during execution.

EXPECTED OUTPUT
[Process exited with code 0 - No output]
main.jsJavaScript
Ctrl + ↵
Execution Console
Click "Run & Verify" (or press Ctrl + Enter) to test your code against the challenge.

Keep exploring.

The official references behind this lesson, when you want a second angle or the full details.

One lesson closer.

Reading is a start. Trying it yourself makes the connection.

Solve the hands-on coding challenge in the knowledge section to verify your code and unlock lesson completion.