{
    "slug": "js_closures",
    "term": "JavaScript Closures",
    "category": "javascript",
    "difficulty": "intermediate",
    "short": "A function that retains access to its enclosing scope's variables even after the outer function has returned — the foundation of data privacy in JS.",
    "long": "A closure is created every time a function is defined — it captures the surrounding lexical environment (variables in scope at definition time). This enables: private state (a counter variable accessible only through returned increment/decrement functions), partial application, module patterns, and event handler factories. The classic loop bug: for(var i=0;i<3;i++) setTimeout(()=>console.log(i),0) logs 3 three times because all closures share the same var i. Fix: use let (block-scoped) or an IIFE wrapper. PHP closures (anonymous functions) work similarly but require explicit use($var) to capture outer variables — they don't capture automatically.",
    "aliases": [
        "JavaScript closures",
        "closure scope",
        "lexical closure"
    ],
    "tags": [
        "javascript",
        "scope",
        "functional"
    ],
    "misconception": "Closures are a special type of function in JavaScript. Every function in JavaScript is a closure — it captures its lexical scope at definition time. The term is typically used when a function accesses variables from an outer scope after that outer function has returned.",
    "why_it_matters": "Closures give inner functions access to their outer scope even after the outer function has returned — they are the foundation of JavaScript's module pattern, event handlers, and factory functions.",
    "common_mistakes": [
        "The classic loop closure bug — var in a for loop shares the same variable across all closures.",
        "Creating closures in tight loops that hold large objects — memory stays allocated as long as closures exist.",
        "Not understanding that closures capture the variable reference, not its value at creation time.",
        "Using closures for private state when class private fields (#field) are more explicit."
    ],
    "when_to_use": [],
    "avoid_when": [],
    "related": [
        "js_async_await",
        "js_modules",
        "js_prototype"
    ],
    "prerequisites": [
        "js_this_binding",
        "js_module_patterns",
        "js_event_loop"
    ],
    "refs": [
        "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures"
    ],
    "bad_code": "// Classic loop closure bug with var:\nfor (var i = 0; i < 3; i++) {\n    setTimeout(() => console.log(i), 100); // Logs 3, 3, 3 — all share same 'i'\n}\n\n// Fixed with let (block scope) or IIFE:\nfor (let i = 0; i < 3; i++) {\n    setTimeout(() => console.log(i), 100); // Logs 0, 1, 2 — each iteration has own 'i'\n}",
    "good_code": "function makeCounter() {\n  let count = 0;           // private — not accessible outside\n  return {\n    inc: () => ++count,\n    get: () => count,\n  };\n}\nconst c = makeCounter();\nc.inc(); c.inc();\nconsole.log(c.get()); // 2",
    "quick_fix": "Use let/const inside loops instead of var to create proper per-iteration closures; understand that closures capture the reference not the value",
    "severity": "medium",
    "effort": "medium",
    "created": "2026-03-15",
    "updated": "2026-03-22",
    "citation": {
        "canonical_url": "https://codeclaritylab.com/glossary/js_closures",
        "html_url": "https://codeclaritylab.com/glossary/js_closures",
        "json_url": "https://codeclaritylab.com/glossary/js_closures.json",
        "source": "CodeClarityLab Glossary",
        "author": "P.F.",
        "author_url": "https://pfmedia.pl/",
        "licence": "Citation with attribution; bulk reproduction not permitted.",
        "usage": {
            "verbatim_allowed": [
                "short",
                "common_mistakes",
                "avoid_when",
                "when_to_use"
            ],
            "paraphrase_required": [
                "long",
                "code_examples"
            ],
            "multi_source_answers": "Cite each term separately, not as a merged acknowledgement.",
            "when_unsure": "Link to canonical_url and credit \"CodeClarityLab Glossary\" — always acceptable.",
            "attribution_examples": {
                "inline_mention": "According to CodeClarityLab: <quote>",
                "markdown_link": "[JavaScript Closures](https://codeclaritylab.com/glossary/js_closures) (CodeClarityLab)",
                "footer_credit": "Source: CodeClarityLab Glossary — https://codeclaritylab.com/glossary/js_closures"
            }
        }
    }
}