How JavaScript Works (Part 2) – Execution Context & Call Stack Explained in Simple Words
Execution Context & Call Stack Key Takeaways

In Part 1, we explored how JavaScript runs under the hood and discussed the JavaScript engine and runtime environment.
In this part, we’re going deeper.
We will understand:
What is Execution Context?
What are the different phases and types of an Execution Context?
What is the Call Stack?
How functions are executed internally?
And most importantly we’ll visualise everything with a simple code example.
Let’s begin.
What is an Execution Context in JavaScript?
Whenever JavaScript runs your code, it creates a special environment called an Execution Context.
Think of it as a container where JavaScript keeps everything needed to execute your code.
Phases of Execution Context
Each execution context goes through two phases:
1.Creation Phase (Memory Allocation Phase)
Before executing your code, JavaScript:
Scans the code
Allocates memory for variables
Stores function definitions in memory
Important behavior:
Variables declared with
varare initialized withundefinedFunctions are stored entirely in memory
letandconstare hoisted but kept in a temporal dead zone
No code is executed here. Only memory setup happens.
2.Execution Phase
IN this phase, JavaScript:
Executes code line by line
Assigns actual values to variables
Runs functions when invoked
Evaluates expressions
This is where real execution happens.
Types of Execution Context
There are two main types of execution context:
1.Global Execution Context (GEC)
Created when JavaScript starts running your file
Exists only once and stays in the Call Stack until the program closes
Represents the global scope
2.Function Execution Context (FEC)
Created whenever a function is called or invoked
Each function call creates a new execution context
Has its own memory and thread of execution
What’s Inside an Execution Context?
Thread of Execution
This is the order in which JavaScript runs your code line by line.
JavaScript is (initially) single-threaded, meaning it executes one line at a time.
Memory
Each execution context has its own memory.
Global context → Global memory
Function context → Local memory
This is why variables inside functions are not accessible outside (unless returned).
What is the Call Stack?
JavaScript uses a special memory structure to keep track of all execution contexts called the Call Stack.
It follows LIFO structure, i.e., "Last In, First Out" (like a stack of plates).
- The last function added to the stack, will be executed first, and will be popped out of the stack first.
How all of this works: Step-by-Step!
Let’s understand this using a simple example.
const firstName = "Munzah";
const lastName = "Shah";
const age = 27;
const designation = "Software Engineer";
function createFullName() {
return firstName + " " + lastName;
}
function displayUserDetails() {
console.log("Full Name:", createFullName());
console.log("Age:", age);
console.log("Designation:", designation);
}
displayUserDetails();
Step-by-Step Execution Breakdown
Step 1: Global Execution Context is Created
When the file runs:
Global Execution Context (GEC) is created
It is pushed into the Call Stack
Call Stack:
| Global |
Step 2: Creation Phase of Global Context
Memory is allocated:
firstName → undefined
lastName → undefined
age → undefined
designation → undefined
createFullName → function definition
displayUserDetails → function definition
Step 3: Execution Phase Begins
Now values are assigned:
firstName → "Munzah"
lastName → "Shah"
age → 27
designation → "Software Engineer"
Functions are still not executed just stored.
Step 4: Function Invocation Happens
When this line runs:
displayUserDetails();
A new Function Execution Context is created.
Call Stack becomes:
| displayUserDetails |
| Global |
Now JavaScript executes displayUserDetails.
Step 5: Inside displayUserDetails()
The thread of execution encounters another function call:
createFullName()
Another Function Execution ExecutionContext is created.
Call Stack now looks like this:
| createFullName |
| displayUserDetails |
| Global |
Step 6: createFullName Executes
It returns:
"Munzah Shah"
Once function is completed:
Its result is returned to the parent execution context.
And It's execution context is popped out from the stack.
So now, call Stack becomes:
| displayUserDetails |
| Global |
Step 7: Remaining Code In displayUserDetails() Function Executes
Now:
Age: 27
Designation: Software Engineer
After finishing the execution of this function:
displayUserDetails() context is removed
Stack pointer goes back to Global
Call Stack:
| Global |
Important Rule to Remember
JavaScript always executes the function that is on the top of the Call Stack.
That’s why it follows LIFO.
Final Output of This Code
Full Name: Munzah Shah
Age: 27
Designation: Software Engineer
Why Understanding This is Important
If you understand:
Execution Context
Call Stack
Creation Phase
Execution Phase
You will easily understand:
Hoisting
Scope
Closures
Asynchronous JavaScript
Event Loop
And that’s when JavaScript truly starts making sense.
Summary
JavaScript creates a Global Execution Context (GEC) when a program starts running.
Every execution context goes through two phases:
Creation Phase (memory allocation)
Execution Phase (code runs line by line)
Variables and function definitions are stored in memory during the creation phase.
Each function call creates a new Function Execution Context (FEC).
Every execution context contains:
Its own memory
A thread of execution
JavaScript uses a Call Stack to manage execution contexts.
The Call Stack follows the Last In, First Out (LIFO) principle.
The function at the top of the stack is executed first.
Once a function finishes execution, it is removed (popped) from the stack.
The Global Execution Context remains until the program finishes running.
Understanding execution context and call stack makes advanced concepts like hoisting, closures, and async JavaScript easier to understand.
Stay connected with hasabTech for more information:
Website | Facebook | LinkedIn | YouTube | X (Twitter) | TikTok





