Alright. Next is a concept that quietly sits under everything JavaScript does. Once you understand it, many confusing things like hoisting, closures, and async behavior start making sense.
Execution Context is the environment where JavaScript code runs and variables/functions are stored.
Whenever JavaScript runs code, it creates an execution context.
There are mainly two types:
- Global Execution Context (GEC)
- Function Execution Context (FEC)
When a JavaScript program starts, the engine creates the Global Execution Context.
Example:
let name = "Nova";
function greet(){
console.log("Hello");
}
greet();Steps JS takes internally:
- Create global execution context
- Store variables and functions in memory
- Execute code line by line
Every execution context runs in two phases.
JavaScript scans the code and allocates memory.
Example:
let x = 10;
function add(a,b){
return a+b;
}Memory phase:
x → undefined
add → function definition
Variables are initialized with undefined first.
Now JavaScript runs the code.
x = 10
function ready to run
Every time a function runs, JavaScript creates a new execution context for that function.
Example:
function add(a,b){
return a + b;
}
add(5,3);Steps:
- Global execution context exists
add()is called- JS creates function execution context
- Parameters get values
- Function executes
- Context is destroyed
The Call Stack keeps track of which function is currently executing.
It works like a stack (LIFO – Last In First Out).
Example:
function one(){
two();
}
function two(){
three();
}
function three(){
console.log("Done");
}
one();Execution order:
Global()
one()
two()
three()
Call Stack behavior:
Push → Global
Push → one
Push → two
Push → three
After finishing:
Pop → three
Pop → two
Pop → one
Output
Done
Code:
function greet(){
console.log("Hello");
}
function start(){
greet();
}
start();Stack flow:
Global()
start()
greet()
Then it unwinds.
If a function keeps calling itself without stopping, the call stack fills up.
Example:
function test(){
test();
}
test();Error:
Maximum call stack size exceeded
This happens in infinite recursion.
Understanding execution context explains:
• hoisting • closures • recursion • async behavior • debugging errors
When developers understand this, debugging becomes much easier.
Predict the output:
function a(){
console.log("A");
}
function b(){
console.log("B");
a();
}
function c(){
console.log("C");
b();
}
c();Expected output:
C
B
A
Call stack order:
Global
c
b
a
Developers who understand Execution Context + Closures + Async JS usually have a strong JavaScript foundation. Many people skip these topics, which later causes confusion in frameworks like React or Node.
If you're continuing your company-level JavaScript path, the next critical topic should be:
Asynchronous JavaScript
because modern apps depend on:
- callbacks
- promises
- async/await
- API requests
- event loop
And this is where JavaScript becomes really powerful — and also confusing for many developers.