Web Fundamentals
JavaScript (JS)
A detailed guide to the V8 engine runtime, event loops, execution contexts, closures, prototypes, asynchronous programming, and performance.
1. V8 Engine Runtime & Compilation
Computers do not understand JavaScript text directly. The V8 engine acts as a translation team to convert code text into raw CPU commands.
- Analogy: The dynamic translation team.
JS Code ──► Parser ──► AST (Abstract Syntax Tree) ──► Ignition (Interpreter)
│ (Bytecode)
▼
TurboFan (JIT Compiler)
│ (Native Machine Code)
▼
CPU- The Parser: Reads the text characters of your code and builds a structured map called the Abstract Syntax Tree (AST).
- The Interpreter (Ignition): A quick translator who translates the AST into bytecode instantly. It starts running code immediately, but executes it slowly.
- The JIT Compiler (TurboFan): A speed specialist. They watch for code loops that run 1000 times (hot spots), compile them directly into raw copper-wire CPU instructions (native machine code), and bypass the interpreter to run them at lightning speed.
2. Call Stack & The Event Loop
JavaScript is single-threaded, meaning it can only perform one task at a time.
- Analogy: A single-chef kitchen with a helper reservation window.
[ Call Stack ] ──► (Async Web API Call) ──► [ Web APIs (Helper) ]
▲ │
│ ▼
(Event Loop) ◄── [ Microtasks (VIP) ] ◄──── (Completes)
▲
│
(Event Loop) ◄── [ Macrotasks (Queue) ] ◄── (Completes)- Call Stack: The chef's immediate order ticket stack. The chef only works on the top ticket (Last In, First Out).
- Web APIs: The kitchen's smart automated helpers (e.g. browser timers, fetch requests). While the helper is waiting for the timer to expire, the chef continues cooking.
- Callback Queue (Macrotasks): A line of completed helper tickets (e.g., click events, timeouts) waiting for the chef.
- Microtask Queue: VIP hot-line tickets (e.g., Promises,
.then()handlers). - Event Loop: The kitchen manager. They wait until the chef's immediate ticket stack (Call Stack) is completely empty. Then, they first check the VIP microtask queue and run all those tickets. Finally, they take the next macrotask ticket from the callback queue and hand it to the chef.
console.log("Start"); // 1. Run immediately on Stack
setTimeout(() => {
console.log("Timeout"); // 4. Queued to Macrotasks
}, 0);
Promise.resolve().then(() => {
console.log("Promise"); // 3. Queued to VIP Microtasks
});
console.log("End"); // 2. Run immediately on Stack
// Output Order: "Start" -> "End" -> "Promise" -> "Timeout"3. Scopes, Hoisting & Closures
Scopes & Hoisting: Setting Up the Stage
- Hoisting: Setting up props on a theatrical stage before the actors begin reading the script.
varis declared and assignedundefinedon the stage floor.letandconstare placed inside a locked glass cabinet (Temporal Dead Zone) until the actor reaches the line that unlocks them.
Closures: The Apartment Wiretap
- Closure: A spy leaving a wiretap bug in an apartment.
- Analogy: When a function finishes running, its local variables (the apartment) are usually cleaned up by garbage collection. But if that function returns an inner function that references those variables, it creates a closure. The inner function acts as a wiretap that remains in the apartment, keeping the memory alive so it can still read the variables long after the parent function has exited.
function createCounter() {
let count = 0; // Stays alive in the apartment
return function() {
count++;
return count;
};
}
const counter = createCounter();
console.log(counter()); // Prints: 1
console.log(counter()); // Prints: 24. Dynamic Binding: this, call, apply, bind
The this keyword refers to the object that is executing the current function.
- Analogy: "Who owns the current phone?" If a phone rings,
thisrefers to whoever is holding the phone at that exact moment.- Implicit: When a method is called on an object, that object is holding the phone (
user.sayName()). - Arrow Functions: Arrow functions are like a phone that has no owner; they simply inherit the ownership (lexical scope) of the room they were built in.
- Implicit: When a method is called on an object, that object is holding the phone (
const person = {
name: "Kamran",
greetNormal: function() {
console.log("Hello, " + this.name); // 'this' points to person
},
greetArrow: () => {
console.log("Hello, " + this.name); // 'this' inherits outer window scope (name is undefined)
}
};call(thisArg, arg1, arg2): Invokes the function immediately, manually handing the phone tothisArg.apply(thisArg, [argsArray]): Same ascall, but arguments are passed as an array.bind(thisArg): Returns a new function with the phone permanently glued tothisArg.
5. Conceptual Quizzes
Knowledge Check
What is the execution order of the logs: console.log('A'); setTimeout(() => console.log('B'), 0); Promise.resolve().then(() => console.log('C')); console.log('D');?
Knowledge Check
What is the Temporal Dead Zone in JavaScript?
6. Practice Problems
Problem 1: Custom Promise Implementation
Write a basic constructor SimplePromise that:
- Supports state transitions from
PENDINGtoRESOLVEDorREJECTED. - Supports chaining using
.then(onResolve).