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:
Sagwan
Mango
Sheesham
Inside the factory, the work is divided into multiple departments
Cutting
Framing
Polishing
Cushion
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:
The very first step is to analyze the wood that has been received.
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
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
Chunks of wood come to the Framing department. On the Framing department blackboard:
What to be done: Frame the received pieces of wood into the given size
Order of work: Smoothen the wood -> Frame into the size of the sofa -> Finishing
A framed sofa comes to the Polishing department. On the Polishing department blackboard:
What to be done: Polish the received sofa frame
Order of work: Apply polish -> Rubbing
A polished sofa comes to the Cushion department. On the Cushion department blackboard:
What to be done: Apply a cushion on the sofa frame
Order of work: Cutting cushion -> Stitching and pasting
A final piece comes to the QA department. On the QA department blackboard:
What to be done: Check the quality and overall sofa
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:
The tasks done are executed on the execution chain. The execution chain is inside the factory
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:
A global execution context is created (also known as the Creation Phase).
Declare the variables and store the definition of functions inside the Memory of the Global Execution Context (also known as Memory Phase).
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).
If there is any function in the code:
Create the Local Execution Context for the function.
Declare the variables in Local Execution Context (also known as Memory Phase for Local Context).
Execute the code of the function line by line.
Once all the code inside the function is executed completely, it returns the value to the Global Context
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)
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 | --------------------------------------------------------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)value1is declared in memory with a valueundefinedvalue2is declared in memory with a valueundefined
The declaration of thesumfunction is stored in memory.
The declaration of thecalculatefunction is stored in memory.resultis declared in the memory with a valueundefinedGlobal Execution Context Memory ________________________________________________________ | window: global object | | this: window | | | | value1: undefined | | value2: undefined | | sum: fn() | | calculate: fn() | | result: undefined | --------------------------------------------------------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
value1is initialized as10.
The value ofvalue2is initialized as20.
Thecalculatefunction 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 | --------------------------------------------------------Creation Phase: Local Execution Context is created for calculate
(Blackboard for the Department is ready)calcNum1is declared in memory with a value10calcNum2is declared in memory with a value20Global 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 | --------------------------------------------------------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)calcNum3is declared in memory with a valueundefinedtotalis declared in memory with a valueundefinedGlobal 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 | --------------------------------------------------------Execution Phase: Execution inside
calculatefunction. Execution of code line by line on main thread.The value of
calcNum3is initialized as30.
Thesumfunction 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)
Creation Phase: Local Execution Context is created for sum
(Blackboard for the Sub-Department is ready)sumNum1is declared in memory with a value10sumNum2is declared in memory with a value20sumNum3is declared in memory with a value30Global 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 | --------------------------------------------------------Memory Phase: SInce there is no variable value needs to be assigned to memory. Nothing will happen for sum function in this phase.
Execution Phase: Sum of 3 variables has been returned by sum function.
The execution context for sum is now destroyed.
Execution Phase: Back to execution of calculate function
The value oftotalis now been updated to60Global 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 | --------------------------------------------------------Execution Phase: The value of
totalis now been returned and the Local Context forcalculateis now destroyed.
Execution Phase: Back to execution of global context
The value ofresultis now been updated to60Global Execution Context Memory ________________________________________________________ | window: global object | | this: window | | | | value1: 10 | | value2: 20 | | sum: fn() | | calculate: fn() | | | | result: 60 | --------------------------------------------------------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.




