JavaScript Notes
Learn exactly how JavaScript runs in the browser and Node.js. Covers execution context, call stack, event loop, Web APIs, callback queue — with diagrams and examples.
Introduction
Have you ever wondered what actually happens when you press "Enter" in the browser console, or when a webpage loads a JavaScript file? How does your code go from text characters to actual running instructions on your computer?
Understanding how JavaScript runs is one of the most important concepts for any JavaScript developer. It explains why some code runs in a certain order, why setTimeout behaves the way it does, and how JavaScript can be "non-blocking" even though it's single-threaded.
Think of it this way: if JavaScript is a car, then knowing how it runs is like understanding the engine — you don't need to build one from scratch, but knowing how it works makes you a far better driver.
Real World Analogy: The Restaurant Kitchen
Imagine JavaScript's execution model as a restaurant kitchen:
Step 1: The Execution Context
When JavaScript starts running your code, it creates an Execution Context — a container that holds all the information needed to run that piece of code.
There are two main types:
1. Global Execution Context (GEC)
Created when your script first loads. There is always exactly one GEC.
// When this file loads, a Global Execution Context is created:
var siteName = "WoHoTech"; // stored in global memory
let lesson = "How JS Runs"; // stored in global memory
function greet(name) { // function stored in global memory
return "Hello, " + name;
}
console.log(greet("Student")); // Hello, StudentHello, Student
2. Function Execution Context (FEC)
Created every time a function is called. Each call creates a brand new context.
function outer() {
let x = 10; // stored in outer's context
function inner() {
let y = 20; // stored in inner's context
console.log(x + y); // x found via scope chain
}
inner(); // new FEC created for inner()
}
outer(); // new FEC created for outer()
// After outer() finishes, its context is destroyed30
The Two Phases of Execution Context
Every execution context goes through two phases:
This explains hoisting — why you can call a function before you write it:
// This works! (function declaration is hoisted)
console.log(sayHello()); // "Hello!" — available before its definition
function sayHello() {
return "Hello!";
}
// This does NOT work the same way
console.log(myVar); // undefined (var hoisted but not assigned yet)
var myVar = "I am here now";
console.log(myVar); // "I am here now"Hello! undefined I am here now
Step 2: The Call Stack
The Call Stack is the mechanism JavaScript uses to keep track of which function is currently running and what to return to when it's done.
Think of it like a stack of plates — you can only add or remove from the top.
Let's see this in real code:
function third() {
console.log("Inside third()");
console.trace(); // Shows the call stack at this moment!
}
function second() {
console.log("Inside second()");
third();
}
function first() {
console.log("Inside first()");
second();
}
first();
console.log("Back in global scope");Inside first() Inside second() Inside third() Trace: at third (script.js:3) at second (script.js:8) at first (script.js:13) at script.js:17 Back in global scope
Stack Overflow — When the Stack Gets Too Full
// This will cause a "Maximum call stack size exceeded" error
function infiniteLoop() {
return infiniteLoop(); // calls itself forever — stack fills up!
}
// infiniteLoop(); // DON'T run this!
// CORRECT: Use recursion with a base case
function countdown(n) {
if (n <= 0) {
console.log("Blast off! 🚀");
return;
}
console.log(n);
countdown(n - 1); // base case will stop this eventually
}
countdown(5);5 4 3 2 1 Blast off! 🚀
Step 3: The Memory Heap
The Memory Heap is where JavaScript stores objects, arrays, and functions — anything that's not a simple primitive value.
// Primitives: stored directly in the call stack (by value)
let a = 10;
let b = a; // b gets a COPY of 10
b = 20;
console.log(a); // 10 — not affected by b's change
console.log(b); // 20
// Objects: stored in the heap (by reference)
let obj1 = { name: "Rahul" };
let obj2 = obj1; // obj2 points to the SAME object in heap
obj2.name = "Priya";
console.log(obj1.name); // "Priya" — both variables point to same object!
console.log(obj2.name); // "Priya"10 20 Priya Priya
Step 4: Web APIs — The Secret Powers
JavaScript's engine is single-threaded, but the runtime environment (browser or Node.js) provides extra capabilities through Web APIs:
// JavaScript itself can't do timers — that's a Web API!
console.log("1: Start");
// setTimeout is a Web API call — handled OUTSIDE the JS engine
setTimeout(function callback() {
console.log("3: Timer fired (after 2000ms)");
}, 2000);
// fetch is also a Web API — network handled by browser
// fetch("https://api.example.com/data").then(...)
console.log("2: End of synchronous code");
// JS engine is now free — Web APIs handle timer in background1: Start 2: End of synchronous code 3: Timer fired (after 2000ms)
Step 5: The Event Loop
The Event Loop is the heart of JavaScript's concurrency model. It continuously monitors:
- Is the Call Stack empty?
- Are there callbacks waiting in the Microtask Queue or Task Queue?
If yes and yes → move the next callback to the call stack.
A D C B
Why? Let's trace it:
Microtask Queue vs Task Queue (Critical Difference!)
--- START --- --- END --- Microtask: Promise 1 Microtask: queueMicrotask Microtask: Promise 2 Task Queue: setTimeout Task Queue: setTimeout 2
Step 6: Synchronous vs Asynchronous Code
Understanding the difference is crucial to writing good JavaScript:
Sync 1 Sync 2 Sync 3
Start End (I ran before the async stuff!) Timer done! ← after 1 second Got data: Linus Torvalds ← after network request completes
The Evolution of Async: Callbacks → Promises → Async/Await
Callback: Rahul Promise: Priya Async/Await: Amit
Step 7: How Node.js Runs JavaScript Differently
In the browser, Web APIs are provided by the browser environment. In Node.js, they come from the C++ bindings of the Node.js runtime:
File read started, not waiting... File contents: [contents of data.txt]
Common Mistakes Beginners Make
1. Expecting setTimeout(fn, 0) to Run Immediately
Before After setTimeout 0ms
2. Not Understanding Async Function Return Values
Promise { <fulfilled>: 42 }
Correct: 42
Also correct: 423. Blocking the Event Loop
Good computation started... Event loop is still responsive! Result: 12499997500000
4. Callback Hell
How JavaScript Code Executes: Complete Step-by-Step
Let's trace through a real example completely:
let x = 10;
function multiply(a, b) {
return a * b;
}
function square(n) {
return multiply(n, n);
}
let result = square(x);
console.log("Result:", result);Result: 100
Step-by-step execution:
Key Takeaways
| Concept | What It Does | Why It Matters |
|---|---|---|
| Execution Context | Container for running code | Explains scope, hoisting, this |
| Call Stack | Tracks which function is running | Explains execution order, stack overflow |
| Memory Heap | Stores objects and functions | Explains reference vs value types |
| Web APIs | Extra capabilities from environment | Explains timers, fetch, DOM events |
| Event Loop | Moves callbacks when stack is empty | Explains async behavior |
| Task Queue | Holds setTimeout/setInterval callbacks | Macro tasks — lowest priority |
| Microtask Queue | Holds Promise callbacks | Higher priority than task queue |
Interview Questions
Q1: What is the JavaScript event loop?
Answer: The event loop is the mechanism that enables JavaScript (a single-threaded language) to perform non-blocking operations. It continuously checks if the call stack is empty, and if so, moves the next callback from the microtask queue (first) or task queue (second) onto the call stack for execution.
Q2: What is the call stack in JavaScript?
Answer: The call stack is a LIFO (Last In, First Out) data structure that tracks function calls. When a function is called, it's pushed onto the stack. When it returns, it's popped off. JavaScript's single thread can only process one stack frame at a time.
Q3: What is the difference between the microtask queue and the task queue?
Answer: The microtask queue (for Promises, queueMicrotask) has higher priority than the task queue (for setTimeout, setInterval). After every task completes, ALL microtasks are processed before the event loop picks the next task. This ensures Promises resolve before the next timer fires.
Q4: What is an execution context?
Answer: An execution context is an environment where JavaScript code is evaluated and executed. It contains the variable environment, scope chain, and the this value. The Global Execution Context is created first; each function call creates a new Function Execution Context.
Q5: Why is JavaScript called single-threaded?
Answer: JavaScript has only one call stack — it can execute only one operation at a time. This prevents race conditions and simplifies programming, but could cause blocking. Web APIs and the event loop provide the illusion of concurrency by handling async operations in the background.
Q6: What happens when you call setTimeout(fn, 0)?
Answer: The callback is sent to the Web API, which after 0ms pushes it to the task queue. The event loop will only pick it up after the current call stack is empty AND all microtasks have been processed. So setTimeout(fn, 0) doesn't mean "immediately" — it means "as soon as possible after current execution."
Q7: What is a stack overflow in JavaScript?
Answer: A stack overflow occurs when the call stack exceeds its maximum size, usually from infinite recursion (a function calling itself without a base case). The error is "Maximum call stack size exceeded." It can be fixed by adding proper base cases to recursive functions.
Q8: What is hoisting in the context of execution context?
Answer: Hoisting happens during the creation phase of an execution context. Function declarations are fully hoisted (available immediately), var declarations are hoisted but initialized as undefined, and let/const are hoisted but remain in the Temporal Dead Zone until their declaration is reached.
Q9: What is the difference between browser JavaScript runtime and Node.js?
Answer: Both use the V8 engine and have a call stack, event loop, and memory heap. The difference is the Web APIs they provide: browsers give you DOM, localStorage, fetch, etc. Node.js gives you file system (fs), HTTP server (http), OS access, and child processes. Node.js doesn't have window, and browsers don't have process.
Q10: What causes a memory leak in JavaScript?
Answer: Memory leaks occur when objects are allocated but never garbage collected. Common causes: global variables that never get cleared, forgotten event listeners, closures holding references to large objects, timers that never clear. The garbage collector can only free objects with no living references.
Summary
JavaScript execution follows a precise order:
- Execution Context is created (global first, then per function call)
- Call Stack tracks the current execution — single-threaded, LIFO
- Memory Heap stores objects and complex data
- Web APIs handle async operations (timers, fetch, DOM events) outside the engine
- Microtask Queue holds Promise callbacks — processed with highest priority
- Task Queue holds macro callbacks (setTimeout) — lower priority
- Event Loop continuously moves callbacks from queues to the call stack
Understanding this model explains every "weird" JavaScript behavior you'll ever encounter — from why setTimeout(fn, 0) doesn't run immediately, to why Promises resolve in a specific order.
What's Next?
In the next lesson, we'll go deeper into the JavaScript Engine — how V8 specifically parses, compiles, and optimizes your code using techniques like JIT compilation, hidden classes, and inline caching.
Exam Focus
Revise definitions, diagrams, examples, and short-answer points for How JavaScript Runs — Complete Guide to Execution, Call Stack & Event Loop.
Interview Use
Prepare one clear explanation, one practical example, and one common mistake for this JavaScript Master Course topic.
Search Terms
javascript-complete-guide, javascript master course, javascript, complete, guide, introduction, how, runs
Related JavaScript Master Course Topics