# Closures — Part 1: The Core Concept

## 1. Definition

A **closure** is a function bundled together with references to its **surrounding lexical scope**. The function keeps access to variables from the scope it was created in, even after that outer scope has finished executing.

```js
function makeGreeter(greeting) {
  return function (name) {
    return `${greeting}, ${name}!`;
  };
}

const greetHello = makeGreeter("Hello");
console.log(greetHello("Ana")); // "Hello, Ana!"
```

`makeGreeter("Hello")` returns and its call stack frame is gone — yet the inner function still reaches `greeting`. That's the closure at work: it didn't copy the value, it kept a **live reference** to the variable.

![outer()'s call frame is gone, but inner() keeps a pointer back to its Context, keeping count alive](diagrams/01-closure-capture.svg)

## 2. How This Works Mechanically

Every function created in JavaScript carries an internal reference to the **lexical environment** it was defined in. As long as any reference to the inner function exists, that environment (and everything it needs) is kept alive by the garbage collector — it is not destroyed just because the outer function returned.

```js
function counter() {
  let count = 0;
  return {
    increment: () => ++count,
    decrement: () => --count,
    value: () => count,
  };
}

const c = counter();
c.increment();
c.increment();
console.log(c.value()); // 2
```

All three inner functions **share the same closure** over `count` — they read and write the same live variable, not separate copies.

## 3. Closures Capture Variables, Not Values

This is the single most important — and most misunderstood — fact about closures.

```js
function badLoop() {
  var fns = [];
  for (var i = 0; i < 3; i++) {
    fns.push(() => console.log(i));
  }
  fns.forEach(fn => fn()); // 3, 3, 3 — NOT 0, 1, 2
}
badLoop();
```

Because `var i` is function-scoped, all three closures capture the **same** `i`. By the time the callbacks run, the loop has finished and `i` is `3`.

```js
function goodLoop() {
  var fns = [];
  for (let i = 0; i < 3; i++) {
    fns.push(() => console.log(i));
  }
  fns.forEach(fn => fn()); // 0, 1, 2 — correct
}
goodLoop();
```

`let` creates a **new binding of `i` for every iteration**, so each closure captures its own independent variable.

## 4. Practical Use: Data Privacy

Because a closure's captured variables aren't accessible from outside, closures are the standard way to create private state in JavaScript without classes:

```js
function createBankAccount(balance) {
  return {
    deposit(amount) { balance += amount; return balance; },
    getBalance() { return balance; },
  };
}
```

`balance` cannot be read or modified except through the returned methods — there is no `account.balance` property at all.

## 5. Common Pitfalls

1. **Loop variable capture with `var`** — the #1 closure bug. Fix with `let`, or by wrapping in an IIFE that captures the value per iteration.
2. **Assuming a closure snapshots a value** — it doesn't; it holds a live reference. If the outer variable changes later, every closure over it sees the new value.
3. **Memory leaks from long-lived closures** — a closure keeps its entire lexical environment alive, not just the variables it uses. Holding a reference to a large object in an outer scope keeps it in memory as long as any inner closure exists.

Continue to `js_closures_theory_2.md` for memory implications and advanced patterns.
