# Closures

A closure is the combination of a function bundled together (enclosed) with references to its surrounding state (the lexical environment). In other words, a closure gives you access to an outer function's scope from an inner function. In JavaScript, closures are created every time a function is created, at function creation time.

## 1. Lexical Scoping

To understand closures, you first need to understand lexical scoping. Lexical scoping means that the scope of a variable is defined by its position in the source code. Nested functions have access to variables declared in their outer scope.

```javascript
function init() {
  var name = "Mozilla"; // name is a local variable created by init
  function displayName() {
    // displayName() is the inner function, a closure
    console.log(name); // use variable declared in the parent function
  }
  displayName();
}
init();
```

## 2. How Closures Work

Consider this example:

```javascript
function makeFunc() {
  const name = "Mozilla";
  function displayName() {
    console.log(name);
  }
  return displayName;
}

const myFunc = makeFunc();
myFunc();
```

In some languages, local variables within a function exist only for the duration of that function's execution. Once `makeFunc()` finishes executing, you might expect the `name` variable to be no longer accessible. However, because the code still works, this is obviously not the case in JavaScript.

The reason is that `myFunc` has become a closure. A closure is a special kind of object that combines two things: a function, and the environment in which that function was created. The environment consists of any local variables that were in-scope at the time the closure was created.

## 3. Practical Use Cases

### Data Privacy / Emulating Private Methods

JavaScript (prior to classes with private fields) didn't have a native way to declare private methods, but closures can emulate them.

```javascript
const counter = (function () {
  let privateCounter = 0;
  function changeBy(val) {
    privateCounter += val;
  }

  return {
    increment() {
      changeBy(1);
    },
    decrement() {
      changeBy(-1);
    },
    value() {
      return privateCounter;
    }
  };
})();

console.log(counter.value()); // 0.
counter.increment();
counter.increment();
console.log(counter.value()); // 2.
counter.decrement();
console.log(counter.value()); // 1.
```

### Function Factories

You can use closures to create functions that add a specific value to their argument.

```javascript
function makeAdder(x) {
  return function (y) {
    return x + y;
  };
}

const add5 = makeAdder(5);
const add10 = makeAdder(10);

console.log(add5(2));  // 7
console.log(add10(2)); // 12
```

## 4. Common Pitfalls: Creating Closures in Loops

Prior to ES6 `let` keyword, a common mistake occurred when creating closures inside loops using `var`. The variable was shared across all closures. The solution is to use `let` (block scope) or an IIFE to create a new scope for each iteration.

[[programming/javascript/vanilla/javascript]]
[[programming/functions-and-scope]]