Skip to main content

Command Palette

Search for a command to run...

JS Internals: Understanding JavaScript Global & Local Execution Context

Published
12 min read
JS Internals: Understanding JavaScript Global & Local Execution Context

Let’s first look at a real-world scenario before jumping into JavaScript.

Imagine a wooden furniture factory that manufactures different types of furniture. To better understand the process, let’s see how the factory works internally.

The factory uses several types of wood. For simplicity, let’s assume the following types are used:

  1. Sagwan

  2. Mango

  3. Sheesham

Inside the factory, the work is divided into multiple departments

  1. Cutting

  2. Framing

  3. Polishing

  4. Cushion

  5. Quality Assurance

There is a centralized execution chain of the factory on which the departments work, and each department performs its task in a specific order in the execution chain.

The entire factory has a central board on which it is mentioned:

  • The order of departments working inside the factory

  • What needs to be done

Inside the department, there will definitely be so many works which are working one by one for their individual task. So, each department also has its own board (or blackboard) where two things are written:

  • The order of individual tasks to be done inside the department

  • The actual tasks that need to be performed in that department

There is also a manager in the factory whose job is to:

  • Monitor the progress of the work

  • Ensure that each department performs its task in the correct order

Let's combine the diagrams to see the full factory view:

Now the factory receives an order to build a wooden sofa with Sagwan wood.

Steps:

  1. The very first step is to analyze the wood that has been received.

  2. On the central factory blackboard:

    • What to be done: Build a sofa with a specific size mentioned

    • Order of work done: Cutting -> Framing -> Polishing -> Cushion -> QA

  3. Wood comes to the Cutting department. On the Cutting department blackboard:

    • What to be done: Cut the wood into a smaller size as mentioned

    • Order of work: Cut big wood logs -> Cutting into smaller chunks

  4. Chunks of wood come to the Framing department. On the Framing department blackboard:

    1. What to be done: Frame the received pieces of wood into the given size

    2. Order of work: Smoothen the wood -> Frame into the size of the sofa -> Finishing

  5. A framed sofa comes to the Polishing department. On the Polishing department blackboard:

    1. What to be done: Polish the received sofa frame

    2. Order of work: Apply polish -> Rubbing

  6. A polished sofa comes to the Cushion department. On the Cushion department blackboard:

    1. What to be done: Apply a cushion on the sofa frame

    2. Order of work: Cutting cushion -> Stitching and pasting

  7. A final piece comes to the QA department. On the QA department blackboard:

    1. What to be done: Check the quality and overall sofa

    2. Order of work: Checking the quality

All of these steps are done under the supervision of the manager and if any process fails in between, the manager can ask the department to do the work again properly.

Things to remember:

  1. The tasks done are executed on the execution chain. The execution chain is inside the factory

  2. There are some sub-tasks inside the department, which are inside the department. But the space allotted to the department is inside the factory, So those subtasks are also belong to the factory.

Javascript program execution works the same way. To understand this, let's replace a few terms with Javascript terminology.

Here,

  • Wood types -> Data types

  • Factory -> Global Execution Context

  • Global Execution has two phases:

    • Code Phase / Thread Phase

    • Memory Phase

  • Departments -> Functions, Functions has its own Local Execution Context, which further has two phases:

    • Code Phase / Thread Phase

    • Memory Phase

  • Manager -> Call Stack, who is responsible for maintaining the order of execution of the functions.

So, whenever a JS code has been executed:

  1. A global execution context is created (also known as the Creation Phase).

  2. Declare the variables and store the definition of functions inside the Memory of the Global Execution Context (also known as Memory Phase).

  3. Now the execution of code starts line by line, which checks the current value of the variables in the memory and reads the definitions of the functions from the memory (also known as Code Phase).

  4. If there is any function in the code:

    1. Create the Local Execution Context for the function.

    2. Declare the variables in Local Execution Context (also known as Memory Phase for Local Context).

    3. Execute the code of the function line by line.

    4. Once all the code inside the function is executed completely, it returns the value to the Global Context

  5. Global Execution Context executes the remaining code until all the code is executed.

Let's take an example to understand the flow:

Here is a small code snippet:

var value1 = 10;
var value2 = 20;

function sum(sumNum1, sumNum2, sumNum3) {
    return sumNum1 + sumNum2 + sumNum3;
}

function calculate(calcNum1, calcNum2) {
  	var calcNum3 = 30;
    var total = sum(calcNum1, calcNum2, calcNum3);
    return total;
}

var result = calculate(value1, value2);
console.log(result);

Steps in which JS code is executed:

Global Execution context (Factory)

  1. Creation Phase
    Global Execution Context is created
    (Blackboard for the factory is ready)

    global is assigned to this (Global can vary depending on the environment in which the code is running. In the browser, it will be a window object.)

    Global Execution Context Memory
    ________________________________________________________
    | window: global object                                |
    | this: window                                         |
    --------------------------------------------------------
    
  2. Memory Phase: Variable and Function Definition get stored in Global Memory
    (What to be done, the size, and the material of the sofa are now mentioned on the blackboard)

    value1 is declared in memory with a value undefined
    value2 is declared in memory with a value undefined
    The declaration of the sum function is stored in memory.
    The declaration of the calculate function is stored in memory.
    result is declared in the memory with a value undefined

    Global Execution Context Memory
    ________________________________________________________
    | window: global object                                |
    | this: window                                         |
    |                                                      |
    | value1: undefined                                    |
    | value2: undefined                                    |
    | sum: fn()                                            |
    | calculate: fn()                                      |
    | result: undefined                                    |
    --------------------------------------------------------
    
  3. Execution Phase: Execution of code line by line. Execution is done by the JS engine on main thread.
    (Sofa building process starts now)

    The value of value1 is initialized as 10.
    The value of value2 is initialized as 20.
    The calculate function is called, so a new Local Execution Context is created and pushed onto the Call Stack.

    Global Execution Context Memory
    ________________________________________________________
    | window: global object                                |
    | this: window                                         |
    |                                                      |
    | value1: 10                                           |
    | value2: 20                                           |
    | sum: fn()                                            |
    | calculate: fn()                                      |
    | result: undefined                                    |
    --------------------------------------------------------
    
    1. Creation Phase: Local Execution Context is created for calculate
      (Blackboard for the Department is ready)

      calcNum1 is declared in memory with a value 10
      calcNum2 is declared in memory with a value 20

      Global Execution Context Memory
      ________________________________________________________
      | window: global object                                |
      | this: window                                         |
      |                                                      |
      | value1: 10                                           |
      | value2: 20                                           |
      | sum: fn()                                            |
      | calculate: fn()                                      |
      |                                                      |
      | Local Execution Context Memory for calculate()       |
      | ---------------------------------------------------- |
      | | this: window                                     | |
      | | calcNum1: 10                                     | |
      | | calcNum2: 20                                     | |
      | | total: undefined                                 | |
      | ---------------------------------------------------- |
      |                                                      |
      | result: undefined                                    |
      --------------------------------------------------------
      
    2. Memory Phase: Variable and Function Definition get stored in Local Memory
      (What to be done and the used things are now mentioned on the department blackboard)

      calcNum3 is declared in memory with a value undefined
      total is declared in memory with a value undefined

      Global Execution Context Memory
      ________________________________________________________
      | window: global object                                |
      | this: window                                         |
      |                                                      |
      | value1: 10                                           |
      | value2: 20                                           |
      | sum: fn()                                            |
      | calculate: fn()                                      |
      |                                                      |
      | Local Execution Context Memory for calculate()       |
      | ---------------------------------------------------- |
      | | this: window                                     | |
      | | calcNum1: 10                                     | |
      | | calcNum2: 20                                     | |
      | | calcNum3: undefined                              | |
      | | total: undefined                                 | |
      | ---------------------------------------------------- |
      |                                                      |
      | result: undefined                                    |
      --------------------------------------------------------
      
    3. Execution Phase: Execution inside calculate function. Execution of code line by line on main thread.

      The value of calcNum3 is initialized as 30.
      The sum function is called, so a new Local Execution Context is created and pushed onto the Call Stack.

      Global Execution Context Memory
      ________________________________________________________
      | window: global object                                |
      | this: window                                         |
      |                                                      |
      | value1: 10                                           |
      | value2: 20                                           |
      | sum: fn()                                            |
      | calculate: fn()                                      |
      |                                                      |
      | Local Execution Context Memory for calculate()       |
      | ---------------------------------------------------- |
      | | this: window                                     | |
      | | calcNum1: 10                                     | |
      | | calcNum2: 20                                     | |
      | | calcNum3: undefined                              | |
      | | total: undefined                                 | |
      | ---------------------------------------------------- |
      |                                                      |
      | result: undefined                                    |
      --------------------------------------------------------
      

      Local Execution Context (Departments)

      1. Creation Phase: Local Execution Context is created for sum
        (Blackboard for the Sub-Department is ready)

        sumNum1 is declared in memory with a value 10
        sumNum2 is declared in memory with a value 20
        sumNum3 is declared in memory with a value 30

        Global Execution Context Memory
        ________________________________________________________
        | window: global object                                |
        | this: window                                         |
        |                                                      |
        | value1: 10                                           |
        | value2: 20                                           |
        | sum: fn()                                            |
        | calculate: fn()                                      |
        |                                                      |
        | Local Execution Context Memory for calculate()       |
        | ---------------------------------------------------- |
        | | this: window                                     | |
        | | calcNum1: 10                                     | |
        | | calcNum2: 20                                     | |
        | | calcNum3: undefined                              | |
        | | total: undefined                                 | |
        | |                                                  | |
        | | Local Execution Context Memory for sum()         | |
        | | ________________________________________________ | |
        | | | this: window                                 | | |
        | | | sumNum1: 10                                  | | |
        | | | sumNum2: 20                                  | | |
        | | | sumNum3: 30                                  | | |
        | | ------------------------------------------------ | |
        | ---------------------------------------------------- |
        |                                                      |
        | result: undefined                                    |
        --------------------------------------------------------
        
      2. Memory Phase: SInce there is no variable value needs to be assigned to memory. Nothing will happen for sum function in this phase.

      3. Execution Phase: Sum of 3 variables has been returned by sum function.

      4. The execution context for sum is now destroyed.

    4. Execution Phase: Back to execution of calculate function
      The value of total is now been updated to 60

      Global Execution Context Memory
      ________________________________________________________
      | window: global object                                |
      | this: window                                         |
      |                                                      |
      | value1: 10                                           |
      | value2: 20                                           |
      | sum: fn()                                            |
      | calculate: fn()                                      |
      |                                                      |
      | Local Execution Context Memory for calculate()       |
      | ---------------------------------------------------- |
      | | this: window                                     | |
      | | calcNum1: 10                                     | |
      | | calcNum2: 20                                     | |
      | | calcNum3: undefined                              | |
      | | total: 60                                        | |
      | ---------------------------------------------------- |
      |                                                      |
      | result: undefined                                    |
      --------------------------------------------------------
      
    5. Execution Phase: The value of total is now been returned and the Local Context for calculate is now destroyed.

  4. Execution Phase: Back to execution of global context
    The value of result is now been updated to 60

    Global Execution Context Memory
    ________________________________________________________
    | window: global object                                |
    | this: window                                         |
    |                                                      |
    | value1: 10                                           |
    | value2: 20                                           |
    | sum: fn()                                            |
    | calculate: fn()                                      |
    |                                                      |
    | result: 60                                           |
    --------------------------------------------------------
    
  5. Execution Phase: console.log reads result from memory and prints 60

Call Stack (Manager)

The Call Stack works like a stack of tasks.

When a function is called, its execution context is pushed onto the stack.

When the function finishes execution, it is popped from the stack.

Single thread

You have heard about that Javascript is single thread language.

That means:

  • Global code runs on main thread

  • When execution of code contains a function

    • A local context is created

    • That context is pushed into Call stack

    • The main thread now start executing the function logic

    • After execution, the local context is removed and destroyed

  • No other thread is created while execution other than main thread.

Function create execution context, not threads

Assignment for practice

Install Node.js (runtime environment) and VSCode (code editor)

Open VSCode, create a file practice.js and copy the above code into that file.

Click on Terminal -> New Terminal from the menu bar on top.

From select terminal, selected "Javascript Debug Terminal".

Add breakpoints by clicking on the gutter (the space). Red dot indicate that the breakpoint is added on that line.

Now, run node practice.js . Make sure you are in the same folder inside the terminal.

Try to play around with the next breakpoint button and observe the values of the context section.

Conclusion

JavaScript executes code using Execution Contexts and the Call Stack.

The Global Execution Context runs first, and every function call creates a new Local Execution Context.

These contexts are managed by the Call Stack to ensure that code executes in the correct order.

Follow the series to learn more about Javascript.

JavaScript: Beginner to Advance 🚀

Part 10 of 14

This blog series is designed for professionals who want to learn JavaScript step by step. Starting from the basics like variables and data types, we gradually move to functions, DOM manipulation, and real-world mini projects.

Up next

Understanding Arrays in JavaScript

When we start learning programming, we usually store values in variables. let fruit1 = "Apple"; let fruit2 = "Banana"; let fruit3 = "Mango"; This works fine for a few values.But what if we need to st