Docs

README

6.1 Execution Context

Introduction

Every time JavaScript runs code, it creates an execution contextβ€”an environment where the code is evaluated and executed. Understanding execution contexts is key to understanding scope, hoisting, this, and closures.


What is an Execution Context?

An execution context is a container that holds information about the environment in which code is currently running.

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚               EXECUTION CONTEXT                         β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                         β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚  β”‚         VARIABLE ENVIRONMENT                      β”‚   β”‚
β”‚  β”‚  β€’ Variable declarations                          β”‚   β”‚
β”‚  β”‚  β€’ Function declarations                          β”‚   β”‚
β”‚  β”‚  β€’ Arguments object                               β”‚   β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β”‚                                                         β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚  β”‚         LEXICAL ENVIRONMENT                       β”‚   β”‚
β”‚  β”‚  β€’ let/const declarations                         β”‚   β”‚
β”‚  β”‚  β€’ Outer environment reference                    β”‚   β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β”‚                                                         β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚  β”‚              THIS BINDING                         β”‚   β”‚
β”‚  β”‚  β€’ What 'this' refers to                          β”‚   β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β”‚                                                         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Types of Execution Contexts

1. Global Execution Context (GEC)

Created when JavaScript first runs your code.

// Global Execution Context
var globalVar = "I'm global";
let globalLet = 'Also global';

function greet() {
  console.log('Hello!');
}

// Everything here is in the Global Execution Context

Characteristics:

  • β€’Only ONE global context per program
  • β€’Creates the global object (window in browsers, global in Node.js)
  • β€’Sets this to the global object
  • β€’Created before any code executes

2. Function Execution Context (FEC)

Created every time a function is called (not declared).

function outer() {
  // New Function Execution Context created
  var outerVar = 'outer';

  function inner() {
    // Another new Function Execution Context
    var innerVar = 'inner';
  }

  inner(); // FEC for inner() created here
}

outer(); // FEC for outer() created here

3. Eval Execution Context

Created when code runs inside eval(). (Rarely used, avoid in practice)

eval('var x = 10;'); // Creates its own execution context

Execution Context Lifecycle

Every execution context goes through two phases:

Phase 1: Creation Phase

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                   CREATION PHASE                        β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                         β”‚
β”‚  1. Create Variable Object (VO)                         β”‚
β”‚     └── Scan for function declarations                  β”‚
β”‚     └── Scan for variable declarations (var)            β”‚
β”‚     └── Set up arguments object                         β”‚
β”‚                                                         β”‚
β”‚  2. Create Scope Chain                                  β”‚
β”‚     └── Current VO + all parent VOs                     β”‚
β”‚                                                         β”‚
β”‚  3. Determine 'this' binding                            β”‚
β”‚                                                         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Phase 2: Execution Phase

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                   EXECUTION PHASE                       β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                         β”‚
β”‚  1. Assign values to variables                          β”‚
β”‚  2. Execute function calls                              β”‚
β”‚  3. Execute code line by line                           β”‚
β”‚                                                         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Visualizing the Phases

function greet(name) {
  var greeting = 'Hello';
  var message = greeting + ', ' + name + '!';
  return message;
}

greet('Alice');

Creation Phase for greet("Alice"):

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚    FUNCTION EXECUTION CONTEXT - greet("Alice")         β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  Creation Phase:                                        β”‚
β”‚                                                         β”‚
β”‚  arguments: { 0: "Alice", length: 1 }                   β”‚
β”‚  name: "Alice"                                          β”‚
β”‚  greeting: undefined  ← hoisted, not yet assigned       β”‚
β”‚  message: undefined   ← hoisted, not yet assigned       β”‚
β”‚  this: global object (or undefined in strict mode)     β”‚
β”‚                                                         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Execution Phase:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Execution Phase (line by line):                        β”‚
β”‚                                                         β”‚
β”‚  Line 2: greeting = "Hello"                             β”‚
β”‚  Line 3: message = "Hello, Alice!"                      β”‚
β”‚  Line 4: return "Hello, Alice!"                         β”‚
β”‚                                                         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

The Global Execution Context in Detail

In Browsers:

// Before any code runs, JavaScript creates:

// Global Object
window = {
    // Browser APIs
    console: {...},
    document: {...},
    setTimeout: function() {...},
    // ... many more
};

// this = window in global scope
console.log(this === window); // true

// Global variables become properties of window
var name = "Alice";
console.log(window.name); // "Alice"

// let and const do NOT become window properties
let age = 25;
console.log(window.age); // undefined

In Node.js:

// Global object is 'global', not 'window'
console.log(global);

// But 'this' at module level is NOT global
console.log(this === global); // false
console.log(this); // {} (module.exports)

// var declarations are NOT added to global
var name = 'Alice';
console.log(global.name); // undefined

Multiple Execution Contexts

var name = 'Global';

function first() {
  var name = 'First';
  second();
  console.log(name); // "First"
}

function second() {
  var name = 'Second';
  console.log(name); // "Second"
}

first();
console.log(name); // "Global"

Execution Flow:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  1. Global Execution Context Created                    β”‚
β”‚     └── name = "Global"                                 β”‚
β”‚     └── first = function                                β”‚
β”‚     └── second = function                               β”‚
β”‚                                                         β”‚
β”‚  2. first() called β†’ FEC for first() created           β”‚
β”‚     └── name = "First"                                  β”‚
β”‚     └── Calls second()                                  β”‚
β”‚                                                         β”‚
β”‚  3. second() called β†’ FEC for second() created         β”‚
β”‚     └── name = "Second"                                 β”‚
β”‚     └── Logs "Second"                                   β”‚
β”‚     └── second() FEC destroyed                          β”‚
β”‚                                                         β”‚
β”‚  4. Back to first()                                     β”‚
β”‚     └── Logs "First"                                    β”‚
β”‚     └── first() FEC destroyed                           β”‚
β”‚                                                         β”‚
β”‚  5. Back to Global                                      β”‚
β”‚     └── Logs "Global"                                   β”‚
β”‚                                                         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Variable Environment vs Lexical Environment

var (Variable Environment)

function example() {
  console.log(x); // undefined (hoisted)
  var x = 10;
  console.log(x); // 10
}

let/const (Lexical Environment)

function example() {
  // console.log(y); // ReferenceError: Cannot access before initialization
  let y = 20;
  console.log(y); // 20
}

The Temporal Dead Zone (TDZ):

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  function example() {                                   β”‚
β”‚      // TDZ for 'y' starts here                         β”‚
β”‚      //                                                 β”‚
β”‚      // console.log(y); ← ReferenceError                β”‚
β”‚      //                                                 β”‚
β”‚      let y = 20; // TDZ ends here                       β”‚
β”‚      console.log(y); // 20                              β”‚
β”‚  }                                                      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Scope Chain in Execution Context

Each execution context has a reference to its outer (parent) environment:

var a = 10;

function outer() {
  var b = 20;

  function inner() {
    var c = 30;
    console.log(a + b + c); // 60
  }

  inner();
}

outer();

Scope Chain:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    SCOPE CHAIN                          β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                         β”‚
β”‚  inner() EC                                             β”‚
β”‚  └── c = 30                                             β”‚
β”‚  └── Outer Reference β†’ outer() EC                       β”‚
β”‚          β”‚                                              β”‚
β”‚          β–Ό                                              β”‚
β”‚  outer() EC                                             β”‚
β”‚  └── b = 20                                             β”‚
β”‚  └── inner = function                                   β”‚
β”‚  └── Outer Reference β†’ Global EC                        β”‚
β”‚          β”‚                                              β”‚
β”‚          β–Ό                                              β”‚
β”‚  Global EC                                              β”‚
β”‚  └── a = 10                                             β”‚
β”‚  └── outer = function                                   β”‚
β”‚  └── Outer Reference β†’ null                             β”‚
β”‚                                                         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

this Binding in Execution Context

this is determined when the execution context is created:

// Global context: this = global object
console.log(this); // window (browser) or global (Node)

const obj = {
  name: 'Object',
  method: function () {
    // Method context: this = obj
    console.log(this.name); // "Object"
  },
  arrow: () => {
    // Arrow function: this = lexical (outer) this
    console.log(this); // window/global
  },
};

obj.method(); // "Object"
obj.arrow(); // window/global

Summary

ConceptDescription
Execution ContextEnvironment where code runs
Global ECCreated first, one per program
Function ECCreated on each function call
Creation PhaseSets up variables, scope, this
Execution PhaseRuns code line by line
Variable EnvironmentHolds var declarations
Lexical EnvironmentHolds let/const, scope chain
Scope ChainLinks to outer environments

Next Steps

In the next section, we'll explore the Call Stackβ€”how JavaScript keeps track of all these execution contexts.

README - JavaScript Tutorial | DeepML