cf.completefrontendCode editorOpen lab
THE JAVASCRIPT FIELD GUIDE

Execution contexts

Understand the global execution context, creation and execution phases, variable environments, and how globalThis and top-level this differ in scripts and modules.

By the end, you can
  • 01
    Describe the global contextExplain the main workspace JavaScript creates before your file runs.
  • 02
    Separate setup from runningPredict what creation phase prepares and what execution phase changes.
  • 03
    Compare scripts and modulesTell when declarations become globalThis properties and what top-level this is.

Every run starts with a workspace

JavaScript does not run a file in empty space. Before the first visible line of code does real work, JavaScript creates an execution context: a workspace for the code that is about to run. This lesson uses a faithful mental model. The exact specification language comes much later in Execution contexts & jobs in the spec and Environment Records, and real engines optimize heavily behind this model.

A context keeps three ideas together: the variable names the code can use, a pointer to the outer scope to search next, and a this value. You already know variables, function locals versus outer variables, closures, and strict mode. Execution contexts connect those ideas to the moment code runs.

Real-life analogyAn execution context is a desk for one job

Imagine every job in an office gets its own desk. Before work starts, the desk gets a notepad listing the names that job may need, a note showing which room to ask next, and a label saying who this is for the job. Running code is the person at the desk filling in and changing that notepad.

In real life: A desk prepared for a task
In JavaScript: One execution context
In real life: A notepad of names and values
In JavaScript: The variable and lexical environments
In real life: A doorway to the room outside
In JavaScript: The outer scope reference
In real life: A name tag that says who is in charge
In JavaScript: The this binding

Where the analogy stops: A real desk is a physical object. Engines are free to store or optimize values in many ways as long as JavaScript behaves as if these desks existed.

The short version

An execution context is the workspace JavaScript creates for the global script or for one function call: variables, an outer link, and a this value travel together.

The global execution context

MAIN OFFICE

The first context is the global execution context. Think of it as the main office for a script or module. Top-level code starts there, and functions declared at the top level are prepared there. When a function is called, JavaScript creates another context on top of the global one; when the function finishes, that context is removed. The Call stack lesson next explores that pushing and popping.

In browser classic scripts, the global context is connected to the global object, which browsers expose as window and all modern JavaScript exposes as globalThis. Do not confuse that object with the whole global environment: top-level let and const are global bindings in classic scripts, but they are not properties on globalThis.

Real-life analogyThe global context is the main office

A company may have one front office everyone can find. Some names are public at reception; other notes stay inside the office. A function call is like setting up a temporary desk for one visitor, then clearing it when the meeting ends.

In real life: The building's front office
In JavaScript: The global execution context
In real life: A public directory at reception
In JavaScript: Global object properties such as classic-script var
In real life: Private notes in the office
In JavaScript: Global lexical bindings from let and const
In real life: Temporary desks for visitors
In JavaScript: Function execution contexts

Where the analogy stops: Modules get their own top-level scope, so the main-office metaphor changes: module declarations do not become public reception-desk properties.

A script that starts in the global contextPop out in the code editor (opens in a new tab)JavaScript
function announce(label) {  let message = label + " #" + count;  console.log(message);} var status = "draft";let count = 1;count = count + 1;announce("Article");

This code begins globally. The body of announce does not run when JavaScript first sees it. It runs only when line 9 calls the function, creating a fresh context with its own parameter and local variable.

Creation phase vs execution phase

STEP THROUGH

Every context has a setup part and a work part. During the creation phase, JavaScript prepares declarations. Function declarations are ready to call. var names exist with undefined. let and const names are known but uninitialized, which is why reading them too early throws a ReferenceError. During the execution phase, JavaScript runs statements line by line and changes values.

What the global context knows before execution starts
NameWhere it is preparedCreation phaseAfter execution
announcefunctionready to callfunction announce
statusvarundefined"draft"
countletuninitialized (TDZ)2

Step through the replay. The first frame is a teaching snapshot of creation-phase state; the later frames are recorded from real functions that compute and print the same output the displayed program prints.

Replay the two phases of a small script
Step 0 of 9Ready
Your turn: follow the blue line

First inspect the creation-phase snapshot. Then step through the execution phase and watch the function call add a new context.

Running in
  1. script
Next: line 1
Click the blue line to take the next stepPop out in the code editor (opens in a new tab)JavaScript
  let message = label + " #" + count;  console.log(message);} var status = "draft";let count = 1;count = count + 1;announce("Article");
CallStoreChangeResultRun = next line. Ran = already executed.
Recent returnsNothing yet. Start with the blue line.
A guided replay recorded from real JavaScript calls, not an engine debugger. Step follows executed statements; Back reviews a snapshot. Reset starts a fresh run.

The Hoisting & the temporal dead zone lesson goes deeper later. For now, keep the simple rule: declarations are set up before code runs, but only some are usable before their declaration line executes.

Early reads: var versus letPop out in the code editor (opens in a new tab)JavaScript
console.log(ready);var ready = "yes"; console.log(count);let count = 1;
Proven behavior

The tests run this as a real script. It logs undefined for the early var read, then throws a ReferenceError on the early let read.

Creation phase or execution phase?
  • Function declaration becomes available before its line executes
  • var count exists with undefined
  • let count is reserved but uninitialized
  • count = count + 1 changes the stored value
  • console.log(message) prints
  • Calling a function pushes a new context
Try it yourself
0 of 6 correct

Sort each event by when it happens. Use the replay above if you are unsure.

Choose a category for every card. You can change an answer at any time; Reset clears them all.

Variable environments

CONCEPTUAL

You will hear two related terms: variable environment and lexical environment. At this stage, use them as a careful mental model rather than spec vocabulary. var belongs to the function or global variable environment. let and const belong to lexical environments, including block scopes. A function call gets its own local environment and points to the outer environment where the function was created.

That outer pointer is the bridge to closures. In the Closures lesson, a function remembers the environment around it. Here, focus on the current call: JavaScript first checks the current context’s notepad, then follows the outer pointer if the name is not there.

Desk inspector: pick a moment
Program being inspectedPop out in the code editor (opens in a new tab)JavaScript
const room = "global";function outer() {  const room = "outer";  inner();}function inner() {  const task = "inspect";  console.log(room, task);}outer();
Context stacktop first

Global execution context

outernone
thisglobalThis in a classic script
outerfunction
innerfunction
roomuninitialized until line 1
Step 1 of 3Global context ready

The main office exists first. Function names are available, and top-level constants will be initialized as their lines run.

A conceptual desk inspector. It is a faithful teaching model, not a live engine memory view.
Variable environment vs lexical environment
IdeaSimple meaningCommon declarationsWhere it matters
Variable environmentThe function/global area that old-style var usesvarFunction scope and classic global object behavior
Lexical environmentA scope record tied to where code is writtenlet, const, parameters, blocksBlock scope, TDZ, closures, shadowing
Outer referenceWhere lookup goes nextA pointer, not a declarationClosures and nested functions

globalThis & this at the top level

INTERACTIVE

globalThis is the standard way to refer to the global object. In browsers, globalThis === window in ordinary same-window code. But top-level this depends on how the code is loaded. A classic sloppy script has top-level this equal to globalThis. An ES module has top-level this equal to undefined. Modules are strict by default, and their top-level declarations stay module-scoped.

Compare top-level and function this
Mode examplePop out in the code editor (opens in a new tab)JavaScript
var scriptVar = "var property";function scriptFunction() {  return "function property";}let scriptLet = "lexical only";const scriptConst = "lexical only"; console.log(this === globalThis);console.log(globalThis.scriptVar);console.log(globalThis.scriptFunction());console.log(globalThis.scriptLet);console.log(globalThis.scriptConst);
Classic scriptresult
Top-level thisglobalThis in a sloppy classic script
var scriptVarcreates globalThis.scriptVar
function scriptFunctioncreates globalThis.scriptFunction
let / constglobal lexical bindings only, not properties
Try it yourself

Classic scripts are the old browser default. Top-level var and function declarations become global object properties; let and const do not.

The tests prove script behavior with vm scripts and module behavior with a real ES module import.
Script, module, and function this
PlaceTop-level or call thisDo declarations become global object properties?
Classic sloppy scriptTop-level this is globalThisTop-level var and functions do; let and const do not
ES moduleTop-level this is undefinedNo top-level declaration becomes a globalThis property
Plain function call, sloppythis defaults to globalThisLocal var stays in the function
Plain function call, strictthis is undefinedLocal var stays in the function
Classic script behaviorPop out in the code editor (opens in a new tab)JavaScript
var scriptVar = "var property";function scriptFunction() {  return "function property";}let scriptLet = "lexical only";const scriptConst = "lexical only"; console.log(this === globalThis);console.log(globalThis.scriptVar);console.log(globalThis.scriptFunction());console.log(globalThis.scriptLet);console.log(globalThis.scriptConst);
ES module behaviorPop out in the code editor (opens in a new tab)JavaScript
var moduleVar = "not a global property";let moduleLet = "module lexical";const moduleConst = "module lexical";function moduleFunction() {  return "module function";} console.log(this === undefined);console.log(globalThis.moduleVar);console.log(globalThis.moduleFunction);console.log(typeof moduleLet);console.log(typeof moduleConst);
Which declarations become global properties?
  • Classic script: `var topic = "contexts";`
  • Classic script: `function start() {}`
  • Classic script: `let topic = "contexts";`
  • Classic script: `const mode = "learn";`
  • ES module: `var topic = "contexts";`
  • ES module: `function start() {}`
Try it yourself
0 of 6 correct

Sort each declaration by what happens in a classic script or ES module.

Choose a category for every card. You can change an answer at any time; Reset clears them all.

Where you’ll use this

Execution contexts explain several bugs professionals see in real code. If a variable logs undefined before its assignment, you are seeing var creation. If a let read crashes before its declaration, you are seeing the temporal dead zone. If a helper accidentally writes to or depends on a global, it is really depending on the global context.

Prefer explicit locals over accidental globalsPop out in the code editor (opens in a new tab)JavaScript
function scoreLabel(score) {  var prefix = "Score";  return prefix + ": " + score;}console.log(scoreLabel(9));console.log(globalThis.prefix);

This helper keeps prefix inside the function context. After the call, globalThis.prefix is still undefined. That is safer than relying on a global var that every script on the page can see.

Common misconceptions

“Creation phase runs my function body.”

It prepares a function declaration. The body runs only when the function is called during execution.

“Hoisting means declarations move in the file.”

The source code does not move. The context is prepared before execution, which can feel like declarations moved.

“Top-level variables are always on globalThis.”

Classic-script var and functions are; classic-script let and const are not. Modules do not add any top-level declarations as global properties.

“Top-level this is always the global object.”

That is true for sloppy classic scripts. It is false in ES modules, where top-level this is undefined.

“The replay is an engine debugger.”

It is a guided replay recorded from real JavaScript calls. It shows the values you need to learn the rule, not the engine’s private optimized memory layout.

Practice: trace the desk

5 EXERCISES
Exercise 1 · Warm-upPredict an early var read

What does the first line print?

Starter codePop out in the code editor (opens in a new tab)JavaScript
console.log(topic);
var topic = "contexts";

Answer, then press Check. Spacing and letter case don’t matter.

    Exercise 2 · PracticeFind the global property

    Which declaration in the starter code does not become a global object property?

    Starter codePop out in the code editor (opens in a new tab)JavaScript
    var scriptVar = "var property";
    let scriptLet = "lexical only";
    console.log(globalThis.scriptVar);
    console.log(globalThis.scriptLet);

    Answer, then press Check. Spacing and letter case don’t matter.

      Exercise 3 · PracticeTrace a nested call

      What does inner() print?

      Starter codePop out in the code editor (opens in a new tab)JavaScript
      let label = "global";
      function outer() {
        let label = "outer";
        inner();
      }
      function inner() {
        console.log(label);
      }
      outer();

      Answer, then press Check. Spacing and letter case don’t matter.

        Exercise 4 · PracticeFix a global-var habit

        Move the shared-looking prefix into the function so it cannot collide with other scripts.

        Starter codePop out in the code editor (opens in a new tab)JavaScript
        var prefix = "Score";
        function scoreLabel(score) {
          return prefix + ": " + score;
        }
          Exercise 5 · ChallengeExplain module top-level this

          In one word, what is top-level this inside an ES module?

          Answer, then press Check. Spacing and letter case don’t matter.

            Quiz: check your understanding

            7 QUESTIONS

            Predict before you choose. Every answer explains the context rule it uses, so a wrong first guess still teaches you something.

            Lesson quiz · 7 questionsScore: first tries count
            1. Question 1 of 7What is an execution context in this lesson's mental model?

              Choose an answer to see the explanation.

            2. Question 2 of 7What does this classic script print before it throws?

              Read the code, then predictPop out in the code editor (opens in a new tab)JavaScript
              console.log(topic);
              var topic = "contexts";
              console.log(count);
              let count = 1;

              Choose an answer to see the explanation.

            3. Question 3 of 7Which setup belongs to the creation phase?

              Choose an answer to see the explanation.

            4. Question 4 of 7In a classic script, which top-level declarations become globalThis properties?

              Choose an answer to see the explanation.

            5. Question 5 of 7What is top-level this in an ES module?

              Choose an answer to see the explanation.

            6. Question 6 of 7What does this program print?

              Read the code, then predictPop out in the code editor (opens in a new tab)JavaScript
              let word = "global";
              function say() {
                let word = "local";
                console.log(word);
              }
              say();
              console.log(word);

              Choose an answer to see the explanation.

            7. Question 7 of 7Why call this a faithful mental model instead of the exact engine implementation?

              Choose an answer to see the explanation.

            Key takeaways

            • An execution context is a workspace for running global code or one function call.
            • The global execution context is created first; function calls create additional contexts.
            • Creation phase prepares declarations; execution phase runs statements and changes values.
            • var belongs to function/global variable environments; let and const use lexical environments and have a TDZ.
            • Classic scripts and ES modules differ: module top-level this is undefined, and module declarations do not become global properties.

            Execution context, one line.
            A JavaScript execution context is the current workspace of bindings, outer scope, and this used while global code or a function call runs.

            Up next: The call stack, where you will zoom in on how JavaScript pushes and pops these contexts as functions call each other.

            CompleteFrontend Clear concepts. Working examples.