JavaScriptโ€ข55 min read

JavaScript Internals 2026: V8 Engine, Event Loop, Closures & More

The ultimate guide to JavaScript internals. Master V8 engine, hoisting, closures, event loop, and memory management with visual diagrams.

Dev Kant Kumar
Dev Kant Kumar
February 20, 2026
2026 Complete Guide

JavaScript Internals

How JS Works Under the Hood - From Engine to Event Loop

Dev Kant Kumar
February 20, 2026
55 min read
JavaScript โ€ข V8 Engine โ€ข Event Loop

Every line of JavaScript you write goes through a breathtaking journey - from raw text to optimized machine code, through execution contexts, call stacks, and event loops. This is the most comprehensive guide on the internet to understanding how JavaScript actually works under the hood. Whether you're preparing for a senior-level interview or simply want to write better code, mastering these internals is what separates good developers from great ones.

Who is this for?

This 20-chapter deep-dive covers everything from V8 engine internals to garbage collection. It's designed for developers who want to go beyond syntax and truly understand the mechanics behind their code. Diagrams, code examples, and real-world analogies are used throughout.

Chapter 01

The Big Picture

Before diving deep, let's trace the complete journey of your JavaScript code - from the moment you write it to the moment it produces results on screen.

JavaScript Code Lifecycle

You write JS code
       โ†“
JS Engine receives it (V8 in Chrome/Node, SpiderMonkey in Firefox)
       โ†“
Parser โ†’ tokenizes โ†’ builds AST (Abstract Syntax Tree)
       โ†“
Interpreter (Ignition) โ†’ converts to Bytecode (runs immediately)
       โ†“
Profiler watches โ†’ hot code โ†’ JIT Compiler (TurboFan) โ†’ optimized Machine Code
       โ†“
Global Execution Context created
       โ†“
Memory Phase โ†’ Code Phase
       โ†“
Call Stack manages execution
       โ†“
Async work โ†’ Web APIs / libuv โ†’ Queues โ†’ Event Loop โ†’ Call Stack

4 Things That Define JavaScript

Single-Threaded

One call stack, one thing at a time. No parallel execution in the main thread.

Non-Blocking

Async operations are offloaded so the main thread never freezes.

Dynamically Typed

Types are checked at runtime, not compile time. Variables can hold any type.

JIT Compiled

Not purely interpreted or compiled - it's a hybrid approach for maximum performance.

Why This Matters

Understanding this flow means you'll know why your code behaves the way it does. Bugs in hoisting, event loop timing, and closure behavior all trace back to these internals.
Chapter 02

JavaScript Engine

The engine is the program that reads and executes your JavaScript. Different browsers and runtimes use different engines, but they all follow the same fundamental principles.

EnvironmentEngineWritten In
Chrome / Node.jsV8C++
FirefoxSpiderMonkeyC / C++
SafariJavaScriptCore (Nitro)C++
Edge (Legacy)ChakraC++

Inside the V8 Engine

V8 has two main components that work together to execute your code:

V8 Engine Architecture

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚               V8 ENGINE                 โ”‚
โ”‚                                         โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
โ”‚  โ”‚   Memory     โ”‚   โ”‚   Call Stack   โ”‚  โ”‚
โ”‚  โ”‚    Heap      โ”‚   โ”‚                โ”‚  โ”‚
โ”‚  โ”‚              โ”‚   โ”‚  (where code   โ”‚  โ”‚
โ”‚  โ”‚ (where objs  โ”‚   โ”‚   executes)    โ”‚  โ”‚
โ”‚  โ”‚  are stored) โ”‚   โ”‚                โ”‚  โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Memory Heap

An unstructured memory pool where objects, arrays, and functions are stored. Memory allocation happens here dynamically as your program runs.

Call Stack

A LIFO data structure that tracks which function is currently executing. Every function call pushes a new frame; every return pops one off.

Chapter 03

How JS Code is Compiled

JavaScript uses JIT (Just-In-Time) Compilation - a hybrid approach that combines the fast startup of an interpreter with the raw speed of a compiler.

JIT Compilation Pipeline

Source Code
     โ†“
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚   PARSER    โ”‚  โ†’ checks syntax, tokenizes code
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
     โ†“
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚     AST     โ”‚  โ†’ Abstract Syntax Tree (tree structure of your code)
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
     โ†“
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ INTERPRETER โ”‚  โ†’ converts to Bytecode, starts executing immediately
โ”‚  (Ignition) โ”‚    (fast startup, slower execution)
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
     โ†“ (profiler detects "hot" functions - called repeatedly)
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚JIT COMPILER โ”‚  โ†’ recompiles hot code into optimized Machine Code
โ”‚ (TurboFan)  โ”‚    (slower to compile, much faster to run)
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
     โ†“
 Machine Code runs directly on CPU

Performance Insight

Writing predictable, consistent code (same types, same object shapes) helps V8 optimize better. Changing types randomly forces V8 to de-optimize, falling back to slower bytecode execution.

What is the AST?

The Abstract Syntax Tree is a tree representation of your code's structure. Every expression, statement, and declaration becomes a node in this tree.

JAVASCRIPTAST Example
// Your code:
const x = 5 + 3

// AST representation (simplified):
{
  type: "VariableDeclaration",
  kind: "const",
  declarations: [{
    type: "VariableDeclarator",
    id: { type: "Identifier", name: "x" },
    init: {
      type: "BinaryExpression",
      operator: "+",
      left: { type: "Literal", value: 5 },
      right: { type: "Literal", value: 3 }
    }
  }]
}

// Visualize any code's AST at โ†’ astexplorer.net
Chapter 04

Execution Context

An Execution Context (EC) is the environment in which JavaScript code is evaluated and executed. Think of it as a container that holds everything needed to run a piece of code.

Three Types of Execution Context

Global Execution Context

Created once when the script starts. this = window (browser) or module (Node.js). Only one exists per program.

Function Execution Context

Created every time a function is called. Each call gets a brand-new EC, even recursive calls to the same function.

Eval Execution Context

Created inside eval(). Avoid using eval - it's a security risk and blocks engine optimizations.

Inside an Execution Context

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚           EXECUTION CONTEXT              โ”‚
โ”‚                                          โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”     โ”‚
โ”‚  โ”‚      Variable Environment       โ”‚     โ”‚
โ”‚  โ”‚  (var declarations, functions)  โ”‚     โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜     โ”‚
โ”‚                                          โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”     โ”‚
โ”‚  โ”‚        Lexical Environment      โ”‚     โ”‚
โ”‚  โ”‚  (let, const, outer reference)  โ”‚     โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜     โ”‚
โ”‚                                          โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”     โ”‚
โ”‚  โ”‚          'this' binding         โ”‚     โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜     โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
Chapter 05

Memory Phase & Code Phase

Every Execution Context is created in two distinct phases. Understanding these phases is the key to understanding hoisting.

Phase 1 - Memory Creation (Hoisting Phase)

The JS engine scans the entire code BEFORE executing a single line:

Memory Allocation Rules

For var declarations  โ†’ stored with value: undefined
For let/const         โ†’ stored but in Temporal Dead Zone (TDZ)
For function declarations โ†’ stored with FULL function definition
For function expressions โ†’ treated like var (undefined)
JAVASCRIPTmemory-phase.js
// What you write:
console.log(a)      // undefined (not error - var hoisted)
console.log(b)      // ReferenceError - TDZ
console.log(greet)  // [Function: greet] - fully hoisted

var a = 10
let b = 20
function greet() { return "hello" }

Memory Phase - Before Any Code Runs

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  Variable Environment                  โ”‚
โ”‚                                        โ”‚
โ”‚  a        โ†’  undefined                 โ”‚
โ”‚  b        โ†’  <TDZ - uninitialized>     โ”‚
โ”‚  greet    โ†’  function greet() {...}    โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Phase 2 - Code Execution Phase

Code runs line by line, top to bottom. Values get assigned to previously allocated memory slots.

Code Execution - Line by Line

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  Line 4: a = 10  โ†’  a updated from undefined to 10  โ”‚
โ”‚  Line 5: b = 20  โ†’  b initialized, TDZ ends         โ”‚
โ”‚  Line 6: greet already stored - no update needed     โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
Chapter 06

Hoisting

Hoisting is the behavior where declarations are processed during the Memory Phase before any code executes. It's not that code physically moves - rather, the engine already knows about declarations before running anything.

var Hoisting

JAVASCRIPT
console.log(x)  // undefined (hoisted, not initialized)
var x = 5
console.log(x)  // 5

// JS sees it as:
var x           // declaration hoisted to top
console.log(x)  // undefined
x = 5           // assignment stays here
console.log(x)  // 5

let & const - Temporal Dead Zone (TDZ)

JAVASCRIPT
console.log(y)  // โŒ ReferenceError: Cannot access 'y' before initialization
let y = 10

// let and const ARE hoisted (JS knows they exist)
// but they're in TDZ from start of scope until declaration line
// accessing them in TDZ = ReferenceError

TDZ Visualized

โ”Œโ”€โ”€ start of scope โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  โ† TDZ for y (exists but not accessible) โ”‚
โ”‚  โ† TDZ for y                             โ”‚
โ”‚  let y = 10  โ† TDZ ENDS here             โ”‚
โ”‚  console.log(y)  โ† safe to access now    โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Function Hoisting

JAVASCRIPT
// Function DECLARATION - fully hoisted
greet()  // โœ… "Hello" - works before declaration
function greet() { console.log("Hello") }

// Function EXPRESSION - NOT fully hoisted (treated like var)
sayHi()  // โŒ TypeError: sayHi is not a function
var sayHi = function() { console.log("Hi") }

// Arrow function - same as function expression
sayBye() // โŒ TypeError
var sayBye = () => console.log("Bye")

Hoisting Summary Table

DeclarationHoisted?Initial ValueAccessible Before Init?
varโœ… Yesundefinedโœ… Yes (gets undefined)
letโœ… YesTDZโŒ No (ReferenceError)
constโœ… YesTDZโŒ No (ReferenceError)
function declarationโœ… YesFull definitionโœ… Yes
function expressionโœ… (as var)undefinedโŒ No (TypeError)
classโœ… YesTDZโŒ No (ReferenceError)
Chapter 07

The Call Stack

The Call Stack is a LIFO (Last In, First Out) data structure that tracks execution contexts. JS can only execute what's on top of the stack.

JAVASCRIPTcall-stack-demo.js
function multiply(a, b) {
    return a * b
}
function square(n) {
    return multiply(n, n)
}
function printSquare(n) {
    const result = square(n)
    console.log(result)
}
printSquare(4)  // Output: 16

Call Stack Step-by-Step

Step 1: Script starts               Step 2: printSquare(4)
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”            โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  Global EC           โ”‚  โ† only    โ”‚  printSquare EC      โ”‚  โ† pushed
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜            โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
                                    โ”‚  Global EC           โ”‚
                                    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Step 3: square(4)                   Step 4: multiply(4,4)
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”            โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  square EC           โ”‚  โ† pushed  โ”‚  multiply EC         โ”‚  โ† TOP
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค            โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚  printSquare EC      โ”‚            โ”‚  square EC           โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค            โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚  Global EC           โ”‚            โ”‚  printSquare EC      โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜            โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
                                    โ”‚  Global EC           โ”‚
                                    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Step 5: multiply returns 16 โ†’ POPPED
Step 6: square returns 16   โ†’ POPPED
Step 7: console.log(16)     โ†’ POPPED
Step 8: printSquare done    โ†’ POPPED
Step 9: Global EC           โ†’ POPPED (program ends)

Stack Overflow

JAVASCRIPT
function infinite() {
    return infinite()  // calls itself forever
}
infinite()
// โŒ RangeError: Maximum call stack size exceeded
// Stack grows until memory runs out - this is a "stack overflow"

Interview Tip

The call stack has a finite size limit (varies by engine, typically ~10,000โ€“25,000 frames). Infinite recursion without a base case will always crash. Use tail-call optimization or convert recursion to iteration for deep call chains.
Chapter 08

Scope & Scope Chain

Scope determines where a variable is accessible. JavaScript has three types of scope, and they nest to form a scope chain.

Three Types of Scope

JAVASCRIPTscope-types.js
// 1. GLOBAL SCOPE
var globalVar = "I'm everywhere"

function example() {
    // 2. FUNCTION SCOPE
    var funcVar = "only inside this function"

    if (true) {
        // 3. BLOCK SCOPE (let/const only)
        let blockVar = "only inside this block"
        var notBlockScoped = "I leak out to function scope"
    }

    console.log(notBlockScoped)  // โœ… accessible (var ignores blocks)
    console.log(blockVar)        // โŒ ReferenceError (let is block scoped)
}

The Scope Chain

When JS looks for a variable, it searches up the chain: Current scope โ†’ Outer scope โ†’ ... โ†’ Global scope โ†’ ReferenceError

JAVASCRIPTscope-chain.js
const a = 'global'

function outer() {
    const b = 'outer'
    function middle() {
        const c = 'middle'
        function inner() {
            const d = 'inner'
            console.log(d)  // โœ… found in own scope
            console.log(c)  // โœ… found in middle scope (1 level up)
            console.log(b)  // โœ… found in outer scope (2 levels up)
            console.log(a)  // โœ… found in global scope (3 levels up)
            console.log(e)  // โŒ ReferenceError - not found anywhere
        }
        inner()
    }
    middle()
}
outer()

Scope Chain Lookup Path

inner() scope  โ†’  middle() scope  โ†’  outer() scope  โ†’  Global scope  โ†’  โŒ ReferenceError
     d                  c                   b                  a

Key Insight

The scope chain is determined by where functions are written (lexical scope), NOT where they are called. This is called lexical scoping - the physical position in your code determines variable access.
Chapter 09

Closures

A closure is a function that remembers the variables from its outer scope even after the outer function has finished executing. This is one of the most powerful and commonly misunderstood concepts in JavaScript.

JAVASCRIPTclosure-basics.js
function makeCounter() {
    let count = 0        // this variable "closes over" into inner function

    return function() {
        count++
        return count
    }
}

const counter = makeCounter()
// makeCounter() has finished - its EC is gone from call stack
// BUT count still lives because the inner function holds a reference

console.log(counter())  // 1
console.log(counter())  // 2
console.log(counter())  // 3

How Closures Work Internally

makeCounter() finishes and pops off call stack
BUT the returned function holds a reference to:
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  Closure (makeCounter scope)       โ”‚
โ”‚  count: 0 โ†’ 1 โ†’ 2 โ†’ 3             โ”‚
โ”‚  (stays in memory heap)            โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
Garbage collector won't clean this
because the inner function still references it

Real-World Uses of Closures

JAVASCRIPTclosure-patterns.js
// 1. DATA PRIVACY (encapsulation)
function createBankAccount(initialBalance) {
    let balance = initialBalance  // private - can't access directly
    return {
        deposit: (amount) => { balance += amount },
        withdraw: (amount) => { balance -= amount },
        getBalance: () => balance
    }
}
const account = createBankAccount(1000)
account.deposit(500)
console.log(account.getBalance())  // 1500
console.log(account.balance)       // undefined - no direct access!

// 2. FUNCTION FACTORIES
function multiply(x) {
    return (y) => x * y     // closes over x
}
const double = multiply(2)
const triple = multiply(3)
double(5)   // 10
triple(5)   // 15

// 3. MEMOIZATION
function memoize(fn) {
    const cache = {}         // closes over cache
    return function(n) {
        if (cache[n]) return cache[n]
        cache[n] = fn(n)
        return cache[n]
    }
}

Classic Closure Gotcha

JAVASCRIPTclosure-gotcha.js
// โŒ BUG - var doesn't create new scope per iteration
for (var i = 0; i < 3; i++) {
    setTimeout(() => console.log(i), 1000)
}
// Output: 3, 3, 3  (NOT 0, 1, 2)
// All closures share the SAME i (var is function scoped)

// โœ… FIX 1 - use let (block scoped, new binding per iteration)
for (let i = 0; i < 3; i++) {
    setTimeout(() => console.log(i), 1000)
}
// Output: 0, 1, 2

// โœ… FIX 2 - use IIFE to create new scope
for (var i = 0; i < 3; i++) {
    ((j) => {
        setTimeout(() => console.log(j), 1000)
    })(i)
}
Chapter 10

The this Keyword

this refers to the object that is currently executing the function. Unlike most languages, it's determined at call time, not definition time (except arrow functions).

5 Rules of this

JAVASCRIPTthis-rules.js
// RULE 1: Global context
console.log(this)  // window (browser) / {} (Node module)

// RULE 2: Object method - this = the object
const user = {
    name: "Dev Kant",
    greet() { console.log(this.name) }  // "Dev Kant"
}
user.greet()

// RULE 3: Regular function - this = undefined (strict) or window
function standalone() {
    console.log(this)  // undefined in strict mode
}
standalone()

// RULE 4: Arrow function - this = inherited from surrounding scope
const obj = {
    name: "Dev Kant",
    greet: () => {
        console.log(this.name)  // undefined! arrow has no own 'this'
    },
    greetCorrect() {
        const arrow = () => console.log(this.name)  // โœ… inherits
        arrow()
    }
}

// RULE 5: Constructor / new keyword - this = newly created object
function Person(name) {
    this.name = name    // this = new empty object
}
const dev = new Person("Dev Kant")
console.log(dev.name)  // "Dev Kant"

Explicitly Setting this

JAVASCRIPT
function introduce(greeting) {
    console.log(`${greeting}, I'm ${this.name}`)
}
const person = { name: "Dev Kant" }

// call - invoke immediately, pass args individually
introduce.call(person, "Hello")

// apply - invoke immediately, pass args as array
introduce.apply(person, ["Hi"])

// bind - returns NEW function with this permanently bound
const boundIntroduce = introduce.bind(person)
boundIntroduce("Hey")

this Summary Table

Contextthis value
Global (browser)window
Global (Node strict){}
Object methodThe object
Regular functionundefined (strict) / window
Arrow functionLexical (from surrounding scope)
new keywordNewly created object
call / apply / bindWhatever you pass
Chapter 11

Prototype & Prototype Chain

Every object in JS has a hidden [[Prototype]] property pointing to another object. This forms the prototype chain - JavaScript's inheritance system.

JAVASCRIPTprototype-basics.js
const arr = [1, 2, 3]
// arr has access to .map(), .filter(), .push() etc.
// but YOU didn't define them - where do they come from?
// Answer: arr โ†’ Array.prototype โ†’ Object.prototype โ†’ null

function Dog(name) {
    this.name = name
}
Dog.prototype.bark = function() {
    console.log(`${this.name} says Woof!`)
}

const dog1 = new Dog("Bruno")
dog1.bark()  // "Bruno says Woof!"

// When JS looks up dog1.bark:
// 1. Check dog1 own properties โ†’ not found
// 2. Check Dog.prototype โ†’ found! โœ… execute it

Prototype Chain

dog1 object
  name: "Bruno"
  [[Prototype]] โ†’ Dog.prototype
                    bark: function
                    [[Prototype]] โ†’ Object.prototype
                                      toString: function
                                      hasOwnProperty: function
                                      [[Prototype]] โ†’ null (end of chain)

ES6 Classes = Prototype Syntax Sugar

JAVASCRIPTclass-sugar.js
// Class syntax (modern, clean)
class Animal {
    constructor(name) { this.name = name }
    speak() { console.log(`${this.name} makes a sound`) }
}

class Dog extends Animal {
    speak() { console.log(`${this.name} barks`) }
}

// Under the hood, JS is STILL using prototypes
// 'extends' sets up the prototype chain
// 'super()' calls the parent constructor
// Classes are just a cleaner API for the same mechanism

Key Takeaway

Classes in JavaScript are not like classes in Java or C++. They're syntactic sugar over prototypal inheritance. The extends keyword simply creates the prototype chain for you.
Chapter 12

Asynchronous JavaScript

JS is single-threaded - it can only do one thing at a time. But the real world needs async operations: network requests, timers, file reads. How does JS handle this without freezing?

The Problem

JAVASCRIPT
// If JS were purely synchronous:
const data = fetch('https://api.example.com/data')  // takes 2 seconds
console.log(data)   // everything FREEZES for 2 seconds
// User can't click, scroll, type - completely blocked

The Solution - Offloading to the Environment

JS doesn't handle async work itself. It hands it off to the environment:

Browser โ†’ Web APIs

fetch, setTimeout, DOM events, localStorage

Node.js โ†’ libuv

File system, network, timers, crypto

Async Offloading Flow

JS (single thread)                  Environment (multi-threaded)
       โ”‚                                      โ”‚
       โ”‚โ”€โ”€ setTimeout(fn, 2000) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ถโ”‚ Timer starts here
       โ”‚                                       โ”‚ JS moves on immediately
       โ”‚โ”€โ”€ fetch(url) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ถโ”‚ HTTP request here
       โ”‚                                       โ”‚
       โ”‚ (continues executing other code)      โ”‚ (handling async in bg)
       โ”‚                                       โ”‚
       โ”‚                          โ—€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”‚ Timer done, response ready
       โ”‚                          (callback/promise pushed to queue)
       โ”‚
    Event Loop picks up from queue when call stack is empty
Chapter 13

Web APIs & libuv

In the Browser - Web APIs

APIPurpose
setTimeout / setIntervalTimer API
fetch / XMLHttpRequestNetwork API
addEventListenerDOM Events API
localStorageStorage API
GeolocationDevice API

In Node.js - libuv

libuv is a C++ library that gives Node.js async I/O capabilities.

OperationHandled By
File System (fs)libuv thread pool
Network (http)OS kernel (epoll/kqueue)
DNS lookupslibuv thread pool
Crypto (heavy)libuv thread pool
Timerslibuv timer mechanism

Node.js Architecture

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                    Your JS Code                     โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                    Node.js APIs                     โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚              V8 Engine    โ”‚    libuv                โ”‚
โ”‚           (executes JS)   โ”‚  (async I/O)            โ”‚
โ”‚                           โ”‚  - Thread Pool (4)      โ”‚
โ”‚                           โ”‚  - Event Loop           โ”‚
โ”‚                           โ”‚  - OS Async             โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
Chapter 14

Task Queue & Microtask Queue

When async operations complete, their callbacks don't go directly to the call stack. They wait in queues, each with different priorities.

Two Queues, Different Priorities

๐Ÿ”ฅ Microtask Queue (HIGH PRIORITY)

  • Promise .then() / .catch() / .finally()
  • async/await continuations
  • queueMicrotask()
  • MutationObserver callbacks

โ†‘ Processed COMPLETELY before any macrotask

๐Ÿ“‹ Macrotask Queue (LOWER PRIORITY)

  • setTimeout / setInterval callbacks
  • setImmediate (Node.js)
  • I/O callbacks
  • UI rendering (browser)

Proof - Queue Priority

JAVASCRIPTqueue-priority.js
console.log('1 - synchronous')

setTimeout(() => console.log('2 - macrotask'), 0)

Promise.resolve().then(() => console.log('3 - microtask'))

console.log('4 - synchronous')

// OUTPUT:
// 1 - synchronous
// 4 - synchronous
// 3 - microtask      โ† runs BEFORE macrotask even with 0ms timeout!
// 2 - macrotask

This Is an Interview Favorite!

The order of execution (sync โ†’ microtasks โ†’ macrotasks) is one of the most commonly asked questions in JavaScript interviews. Understanding why microtasks run before macrotasks requires understanding the event loop - covered next.
Chapter 15

The Event Loop

The Event Loop is the heart of JavaScript's asynchronous model. It bridges the call stack to the task queues, ensuring non-blocking execution.

The Event Loop Algorithm

Event Loop Tick - Exact Order

1. Execute ALL synchronous code (drain the call stack)
2. Process ALL microtasks (drain microtask queue completely)
   โ†’ if microtasks add more microtasks, process those too
   โ†’ keep going until microtask queue is EMPTY
3. Pick ONE macrotask from macrotask queue
4. Execute it (may add to call stack)
5. Process ALL microtasks again (step 2)
6. Render (browser only - if needed)
7. Pick next macrotask (step 3)
8. Repeat forever

Full Event Loop Diagram

Complete Event Loop Architecture

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                      YOUR CODE                           โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                         โ”‚
                         โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                     CALL STACK                            โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                                        โ”‚
โ”‚  โ”‚  current fn  โ”‚  โ† executes one thing at a time        โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                                        โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
     โ”‚ empty?                      โ”‚ async call?
     โ”‚                             โ–ผ
     โ”‚              โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
     โ”‚              โ”‚  WEB APIs / libuv             โ”‚
     โ”‚              โ”‚  setTimeout โ†’ timer           โ”‚
     โ”‚              โ”‚  fetch โ†’ HTTP request         โ”‚
     โ”‚              โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
     โ”‚                         โ”‚ work done
     โ”‚              โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
     โ”‚         โ”Œโ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”
     โ”‚         โ”‚ MICROTASK     โ”‚   โ”‚   MACROTASK      โ”‚
     โ”‚         โ”‚ QUEUE         โ”‚   โ”‚   QUEUE          โ”‚
     โ”‚         โ”‚ (promises)    โ”‚   โ”‚ (setTimeout etc) โ”‚
     โ”‚         โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
     โ”‚              โ”‚ priority โ†‘        โ”‚ lower priority
     โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                    โ†‘
               EVENT LOOP
         (bridges queues โ†’ stack)
         checks: is call stack empty?
         โ†’ yes: push next task
         โ†’ no: wait

Microtask Starvation (Edge Case)

JAVASCRIPTstarvation.js
// โš ๏ธ This will NEVER execute the setTimeout!
function keepAddingMicrotasks() {
    Promise.resolve().then(keepAddingMicrotasks)
    // keeps adding to microtask queue infinitely
    // event loop never gets to macrotask queue
}
keepAddingMicrotasks()
setTimeout(() => console.log('never runs'), 0)

// The microtask queue never empties, so the macrotask
// (setTimeout callback) is starved and never executes

Critical Warning

Microtask starvation can freeze your entire application. If microtasks keep spawning more microtasks, macrotasks (including UI rendering) will never execute. Always ensure your microtask chains have a definite end.
Chapter 16

Promises Internals

A Promise is an object representing the eventual completion or failure of an asynchronous operation.

Three States of a Promise

Promise State Machine

PENDING โ”€โ”€โ”€โ”€ resolve(value) โ”€โ”€โ”€โ”€โ–ถ FULFILLED โœ…
     โ”‚
     โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€ reject(reason) โ”€โ”€โ”€โ”€โ–ถ REJECTED โŒ

Once settled (fulfilled or rejected), state NEVER changes.
A promise can only transition ONCE.

How Promises Work Internally

JAVASCRIPTpromise-internals.js
// When you create a Promise:
const p = new Promise((resolve, reject) => {
    // executor runs SYNCHRONOUSLY immediately
    setTimeout(() => resolve(42), 1000)
})

// p is in PENDING state right now

p.then(value => console.log(value))
// .then() registers a callback - doesn't run yet
// when resolve(42) fires after 1 second:
// โ†’ callback goes to MICROTASK QUEUE
// โ†’ event loop picks it up โ†’ runs it โ†’ prints 42

Promise Chaining

JAVASCRIPT
fetch('/api/user')
    .then(response => response.json())      // returns new Promise
    .then(data => data.name)               // returns new Promise
    .then(name => console.log(name))       // chain continues
    .catch(err => console.error(err))      // catches any error above
    .finally(() => console.log('done'))    // always runs

// Each .then() returns a NEW Promise - this enables chaining

Promise Static Methods

MethodResolves WhenRejects When
Promise.all()ALL resolveANY rejects
Promise.allSettled()ALL settle (always)Never rejects
Promise.race()First to settleFirst to settle
Promise.any()First SUCCESSALL reject
Chapter 17

async/await Internals

async/await is syntactic sugar over Promises. It makes async code look synchronous while behaving the same way under the hood.

JAVASCRIPTasync-vs-promise.js
// Promise version
function getUser() {
    return fetch('/api/user')
        .then(res => res.json())
        .then(data => data.name)
}

// async/await version - same thing, cleaner syntax
async function getUser() {
    const res = await fetch('/api/user')   // pauses HERE
    const data = await res.json()         // pauses HERE
    return data.name
}

What Actually Happens with await

JAVASCRIPTawait-flow.js
async function example() {
    console.log('A')
    const result = await Promise.resolve(42)
    // Everything AFTER await goes into microtask queue
    console.log('B', result)  // this runs later
}

console.log('1')
example()
console.log('2')

// Output:
// 1
// A        โ† async function starts synchronously
// 2        โ† continues synchronous code after example() call
// B 42     โ† microtask runs after call stack clears

async/await Execution Flow

async function hits await
        โ†“
pauses function execution
registers continuation as microtask
        โ†“
returns control to caller
        โ†“
caller continues synchronously
        โ†“
call stack empties
        โ†“
event loop picks up continuation from microtask queue
        โ†“
async function resumes after await line

Error Handling with try/catch

JAVASCRIPTasync-error.js
async function getData() {
    try {
        const res = await fetch('/api/data')
        if (!res.ok) throw new Error('HTTP error!')
        const data = await res.json()
        return data
    } catch (err) {
        console.error('Failed:', err.message)
    } finally {
        console.log('cleanup always runs')
    }
}
Chapter 18

Memory Management & Garbage Collection

JS automatically manages memory - you don't free it manually like C/C++. Understanding how it works helps you avoid memory leaks.

Memory Lifecycle

Three Stages of Memory

1. ALLOCATE   โ†’ JS allocates memory when you declare variables, objects
2. USE        โ†’ read/write the value
3. RELEASE    โ†’ garbage collector frees memory when no longer needed

Garbage Collection - Mark & Sweep

V8 Mark & Sweep Algorithm

1. Start from "roots" (global variables, call stack variables)
2. Mark everything reachable from roots
3. Sweep (delete) everything NOT marked
4. Compact memory (optional - reduces fragmentation)

"Reachable" = can be accessed from root via references
"Unreachable" = garbage, will be collected

Common Memory Leaks

JAVASCRIPTmemory-leaks.js
// โŒ LEAK 1: Accidental globals
function leak() {
    forgotVar = "I'm global now"  // no let/const/var โ†’ goes to window
}

// โŒ LEAK 2: Forgotten timers
const data = hugeDataSet
setInterval(() => {
    processData(data)  // data is never freed, timer keeps reference
}, 1000)
// Always clearInterval() when done!

// โŒ LEAK 3: Detached DOM nodes
let element = document.getElementById('btn')
document.body.removeChild(element)  // removed from DOM
// BUT element variable still holds reference - NOT garbage collected
element = null  // โœ… fix: explicitly null the reference

// โŒ LEAK 4: Closures holding large data
function process() {
    const bigData = new Array(1000000).fill('data')
    return function() {
        // closes over bigData even if not using it
        return 'done'
    }
}

Pro Tip

Use Chrome DevTools Memory tab to detect leaks. Take heap snapshots before and after user actions - if memory keeps growing without being released, you have a leak.
Chapter 19

Complete Flow Diagram

Here's the master diagram that ties every concept together - from source code to execution to async handling. This is the single most important visualization in this entire guide.

JavaScript Complete Flow - Master Diagram

SOURCE CODE
    โ”‚
    โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚   JS ENGINE (V8)    โ”‚
โ”‚  Parser             โ”‚ โ†’ tokenize โ†’ AST
โ”‚  Ignition           โ”‚ โ†’ bytecode (fast start)
โ”‚  TurboFan           โ”‚ โ†’ machine code (hot paths)
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
           โ”‚
           โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚              GLOBAL EXECUTION CONTEXT            โ”‚
โ”‚                                                  โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”‚
โ”‚  โ”‚           MEMORY PHASE                   โ”‚   โ”‚
โ”‚  โ”‚  var โ†’ undefined                         โ”‚   โ”‚
โ”‚  โ”‚  let/const โ†’ TDZ                         โ”‚   โ”‚
โ”‚  โ”‚  function โ†’ full definition              โ”‚   โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ”‚
โ”‚                                                  โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”‚
โ”‚  โ”‚           CODE PHASE                     โ”‚   โ”‚
โ”‚  โ”‚  line by line execution                  โ”‚   โ”‚
โ”‚  โ”‚  values assigned                         โ”‚   โ”‚
โ”‚  โ”‚  functions called โ†’ new EC created       โ”‚   โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
           โ”‚
           โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”     โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚     CALL STACK      โ”‚     โ”‚    WEB APIs / libuv           โ”‚
โ”‚                     โ”‚โ”€โ”€โ”€โ”€โ–ถโ”‚  setTimeout โ”€โ”€โ–ถ timer        โ”‚
โ”‚  [current EC]       โ”‚     โ”‚  fetch โ”€โ”€โ”€โ”€โ”€โ”€โ–ถ HTTP          โ”‚
โ”‚  [outer EC]         โ”‚     โ”‚  fs.read โ”€โ”€โ”€โ”€โ–ถ disk I/O      โ”‚
โ”‚  [Global EC]        โ”‚โ—€โ”€โ”€โ”€โ”€โ”‚                              โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜     โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
           โ–ฒ                               โ”‚ done
           โ”‚                    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
           โ”‚             โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”
           โ”‚             โ”‚  MICROTASK   โ”‚  โ”‚  MACROTASK    โ”‚
           โ”‚             โ”‚    QUEUE     โ”‚  โ”‚    QUEUE      โ”‚
           โ”‚             โ”‚ Promise.then โ”‚  โ”‚ setTimeout cb โ”‚
           โ”‚             โ”‚ await cont.  โ”‚  โ”‚ setInterval   โ”‚
           โ”‚             โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
           โ”‚                    โ”‚ priority 1       โ”‚ priority 2
           โ”‚                    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
           โ”‚                    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
           โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”‚   EVENT LOOP     โ”‚
                                โ”‚ 1. stack empty?  โ”‚
                                โ”‚ 2. drain micros  โ”‚
                                โ”‚ 3. one macro     โ”‚
                                โ”‚ 4. repeat        โ”‚
                                โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
Chapter 20

Quick Reference Cheatsheet

Execution Context

Global EC   โ†’ created once, window/global as 'this'
Function EC โ†’ created on every function call
Both have   โ†’ Memory Phase + Code Phase

Hoisting

var         โ†’ hoisted, initialized to undefined
let/const   โ†’ hoisted, in TDZ (ReferenceError)
function    โ†’ fully hoisted with body
func expr   โ†’ hoisted as var (undefined)

Scope

var         โ†’ function scoped (ignores blocks)
let/const   โ†’ block scoped
Scope chain โ†’ inner โ†’ outer โ†’ global โ†’ ReferenceError

Closures

Function + its outer scope references = closure
Outer function can finish, inner still has access
Used for: data privacy, factories, memoization

this Keyword

Global    โ†’ window / undefined (strict)
Method    โ†’ the object
Arrow fn  โ†’ lexical (from surrounding scope)
new       โ†’ new object
call/applyโ†’ explicitly set

Async Priority Order

1. Synchronous code (call stack)
2. Microtask queue (ALL) - Promises, await
3. ONE Macrotask - setTimeout, I/O
4. Microtask queue again (ALL)
5. Next Macrotask - repeat

Memory

Heap   โ†’ objects, arrays, functions stored here
Stack  โ†’ primitives + references stored here
GC     โ†’ mark & sweep, removes unreachable objects
Leaks  โ†’ globals, forgotten timers, detached DOM, closures
๐Ÿ“–Read: You Don't Know JS (free on GitHub) - github.com/getify/You-Dont-Know-JS
๐ŸŽฌWatch: "What the heck is the event loop?" - Philip Roberts (JSConf EU, YouTube)
๐Ÿ’ปPractice: javascript.info - best interactive JS reference
๐Ÿ”Visualize: latentflip.com/loupe - visualize call stack + event loop live
๐ŸŒณAST Explorer: astexplorer.net - see how V8 parses your code

Notes by Dev Kant Kumar | JavaScript Mastery Journey 2026

Recommended Resources
How To Practice Coding Every Day
Han Shavir

Build a Consistent Coding Habit

Stop guessing and start building. This e-book provides practical strategies, exercises, and routines to help you code regularly and improve steadily.

Get E-Book
How to Read and Understand Other People's Code
Han Shavir

Master Unfamiliar Codebases

Struggling to make sense of someone else's code? Learn practical strategies to navigate, analyze, and master unfamiliar codebases with confidence.

Get E-Book

Tags

#javascript#v8-engine#event-loop#closures#hoisting#execution-context#call-stack#scope-chain#prototypes#async-await#promises#garbage-collection#web-development#javascript-internals#interview-preparation
Dev Kant Kumar

Dev Kant Kumar

Author

Full Stack Developer passionate about crafting high-performance user experiences. I write about Agentic AI, React, and the future of web development.

๐Ÿ’ฌ Discussion

Recommended Resources
How To Practice Coding Every Day
Han Shavir

Build a Consistent Coding Habit

Stop guessing and start building. This e-book provides practical strategies, exercises, and routines to help you code regularly and improve steadily.

Get E-Book
How to Read and Understand Other People's Code
Han Shavir

Master Unfamiliar Codebases

Struggling to make sense of someone else's code? Learn practical strategies to navigate, analyze, and master unfamiliar codebases with confidence.

Get E-Book