If you've ever wondered how JavaScript handles your code behind the scenes—especially with functions, asynchronous operations, and callbacks—then this blog is for you.
Let’s explore the JavaScript engine's internal workflow and understand how everything from function execution to setTimeout actually works.
⚙️ The JavaScript Engine
At the core of your browser lies the JavaScript Engine (like V8 for Chrome, SpiderMonkey for Firefox). It’s responsible for:
- Parsing your code
- Compiling it (Just-In-Time compilation)
- Executing it
JavaScript is single-threaded and non-blocking, which is made possible thanks to the Event Loop, Web APIs, and the Callback Queue.
🧠 Execution Context
When you run JS code, an Execution Context is created.
Types of Execution Contexts:
- Global Execution Context (GEC) – Created when script first runs.
- Function Execution Context (FEC) – Created every time a function is invoked.
-
Eval Execution Context – (Rarely used) created by
eval()
.
Each context contains:
- Variable Environment
- Scope Chain
-
this
binding
Example:
function greet() {
var name = "Nadim";
console.log("Hello", name);
}
greet();
Here, calling greet()
creates a new Function Execution Context on top of the Global one.
📚 Call Stack
The Call Stack tracks the execution of function calls.
How It Works:
- When a function is called, it’s pushed onto the stack.
- When the function completes, it’s popped off the stack.
function a() {
b();
}
function b() {
c();
}
function c() {
console.log("Done");
}
a();
Call Stack: a
→ b
→ c
→ logs “Done” → unwinds in reverse.
🌀 Event Loop + Callback Queue
JavaScript uses Event Loop to handle async operations like setTimeout
, API calls, etc.
Components Involved:
- Call Stack
- Web APIs
- Callback Queue
- Event Loop
Example:
console.log("Start");
setTimeout(() => console.log("Timeout"), 0);
console.log("End");
Output:
Start
End
Timeout
Why? Because setTimeout
is handled by Web API and pushed to the Callback Queue. Only after the Call Stack is empty does the Event Loop push the callback.
🧪 Microtasks vs Macrotasks
- Microtasks (Promises, MutationObserver)
-
Macrotasks (
setTimeout
,setInterval
, etc.)
Microtasks are given priority over macrotasks.
Promise.resolve().then(() => console.log("Promise"));
setTimeout(() => console.log("Timeout"), 0);
console.log("End");
Output:
End
Promise
Timeout
🛠️ Summary
- Execution Context: Where code runs (Global or Function).
- Call Stack: Tracks active functions.
- Web APIs: Handle async tasks.
- Callback Queue: Queued callbacks waiting to execute.
- Event Loop: The traffic cop that ensures smooth async execution.
- Microtasks/Macrotasks: Determine task priority.
✅ Interview Tip
Always be prepared to draw or walk through the call stack and event loop behavior in a whiteboard round. Understanding this is key to writing efficient async code.
🔗 Follow for more: GitHub | YouTube | LinkedIn | X | Insta | ☕ Support
Disclaimer: This content has been generated with the assistance of AI. While I strive for accuracy and quality, please verify critical information independently.