JavaScript Closures Cheat Sheet
Covers how closures capture variables from their enclosing scope, with practical patterns like private state, memoization, and a classic loop pitfall.
1 PageIntermediateApr 5, 2026
What Is a Closure
A function remembers the scope it was created in.
javascript
function makeCounter() { let count = 0; // "Private" variable return function () { count += 1; // Inner function "closes over" count return count; };}const counter = makeCounter();counter(); // 1counter(); // 2counter(); // 3 -- count persists between calls, isolated per counter instanceconst counter2 = makeCounter();counter2(); // 1 -- independent state from `counter`
Private State / Module Pattern
Expose only the operations you want, hide the rest.
javascript
function createBankAccount(initialBalance) { let balance = initialBalance; // Not accessible from outside return { deposit(amount) { balance += amount; return balance; }, withdraw(amount) { if (amount > balance) throw new Error("Insufficient funds"); balance -= amount; return balance; }, getBalance() { return balance; }, };}const account = createBankAccount(100);account.deposit(50); // 150// account.balance is undefined -- no direct access
The Classic Loop Pitfall
var vs let inside async callbacks.
javascript
// Bug: `var` is function-scoped, shared across all callbacksfor (var i = 0; i < 3; i++) { setTimeout(() => console.log(i), 100); // Logs 3, 3, 3}// Fix 1: use `let`, which is block-scoped (new binding per iteration)for (let i = 0; i < 3; i++) { setTimeout(() => console.log(i), 100); // Logs 0, 1, 2}// Fix 2: create a new scope with an IIFEfor (var i = 0; i < 3; i++) { ((i) => setTimeout(() => console.log(i), 100))(i);}
Memoization with Closures
Cache expensive results in a closed-over Map.
javascript
function memoize(fn) { const cache = new Map(); return function (...args) { const key = JSON.stringify(args); if (cache.has(key)) return cache.get(key); const result = fn(...args); cache.set(key, result); return result; };}const slowSquare = (n) => { for (let i = 0; i < 1e6; i++); return n * n; };const fastSquare = memoize(slowSquare);fastSquare(5); // ComputedfastSquare(5); // Returned from cache
Key Concepts
Core vocabulary for closures.
- Lexical scope- A function's scope is determined by where it's defined in the source, not where it's called
- Closure- A function bundled with references to its surrounding variables, which stay alive as long as the closure exists
- Free variable- A variable used in a function but not declared locally, captured from an outer scope
- IIFE- Immediately Invoked Function Expression, historically used to create isolated scope
- Garbage collection- Variables captured by a closure aren't collected until the closure itself is no longer reachable
Pro Tip
Closures keep their entire enclosing scope alive, not just the variables they reference — holding a long-lived closure over a large object (e.g. inside an event listener you never remove) is a common source of memory leaks.
Was this cheat sheet helpful?
Explore Topics
#JavaScriptClosures#JavaScriptClosuresCheatSheet#Programming#Intermediate#WhatIsAClosure#Private#State#Module#Functions#CheatSheet#SkillVeris
Advertisement
Sri Hayavadhana Info-Tech
Professional Web Designing Services
- Responsive Websites
- E-commerce Solutions
- SEO Friendly Design
- Fast & Secure
- Support & Maintenance