What is a closure? Example use cases in JavaScript and React
Tags: javascript, react, webdev, programming
Published: 2022-05-09 15:02:51

## What is a closure?

If you are not completely new to JavaScript and are unfamiliar with closures, you have probably used a closure without knowing it. A closure is when a function has access to variables (can read and change them) defined in its outer scope,  even when the function is executed outside of the scope where it was defined.  A closure is a function enclosing a reference (variable) to its outer scope. Functions can access variables outside of their scope.

Here is a simple example where an outer function that returns an inner function has access to a variable in the outer function:

```javascript
function outerFunction() {
  let outerFuncVar = "outside";
  function innerFunction() {
    console.log(`The value is: ${outerFuncVar}`);
  }
  return innerFunction();
}

outerFunction();
```

Console output: `The value is: outside`

&nbsp;

The outer function returns an inner function that "closes" over the outer function variable `outerFuncVar`. This is why it is called a closure. The `outerFunction`, which returns the `innerFunction`, can be called anywhere outside of its scope and the `innerFunction` will have access to, it can remember, the `outerFuncVar`. When it is called, it can read the value of this variable.



Let's modify the above example so that the `outerFunction` variable can be changed and new value is logged after 5 seconds has passed:

```javascript
function outerFunction(input) {
  let outerFuncVar = input;
  function innerFunction() {
    setTimeout(() => {
      console.log(`The value is: ${input}`);
    }, 5000);
  }
  return innerFunction();
}

outerFunction("new value");
```

Console output: `The value is: new value`

&nbsp;

Even after `outerFunction` has finished executing in the above example, the `outerFuncVar` is still accessible 5 seconds after the function was called. JavaScript automatically allocates memory when variables are initially declared. After a function returns, its local variables may be marked for garbage collection and removed from memory. Garbage collection is a type of automatic memory management used by JavaScript to free memory when an allocated block of memory, such as a variable and its value, is not needed anymore. 

If the `outerFuncVar` was garbage collected right after the function call, it would cause an error because the  `outerFuncVar` would no longer exist. The `outerFuncVar` is not garbage collected because JavaScript works out that the nested `innerFunction` may still be called as it is used in a closure. JavaScript does memory management for us, unlike low-level languages such as C.



You can also see this persistence of the closures reference to an outer variable by returning the `innerFunction` from the `outerFunction` and storing it in a variable before executing the `innerFunction`: 

```javascript
function outerFunction() {
  let outerFuncVar = "outside";
  function innerFunction() {
    console.log(`The value is: ${outerFuncVar}`);
  }
  return innerFunction;
}

const innerFunct = outerFunction();
innerFunct();
```

Console output: `The value is: outside`

&nbsp;

If the outer function is a nested function itself , such as `outerOuterFunction` in the code below, all of the closures will have access to all of their outer function scopes. In this case the `innerFunction` closure has access to the `outerFunction` and `outerOuterFunction` variables:

```javascript
function outerOuterFunction() {
  let outerOuterFuncVar = "outside outside";
  return function outerFunction() {
    let outerFuncVar = "outside";
    function innerFunction() {
      console.log(`The outerFunction value is: ${outerFuncVar}`);
      console.log(`The outerOuterFunction value is: ${outerOuterFuncVar}`);
    }
    return innerFunction;
  };
}

const outerFunct = outerOuterFunction();
const innerFunct = outerFunct();
innerFunct();
```

Console output: 
`The outerFunction value is: outside`
`The outerOuterFunction value is: outside outside`


&nbsp;


Multiple instances of a closure can also be created with independent variables that they close over. Let's look at a counter example:

```javascript
function counter(step) {
  let count = 0;
  return function increaseCount() {
    count += step;
    return count;
  };
}

let add3 = counter(3); // returns increaseCount function. Sets step and count to 3
let add5 = counter(5); // returns increaseCount function. Sets step and count to 5

add3(); // 3
console.log(add3()); // 6

add5(); // 5
add5(); // 10
console.log(add5()); // 15
```

&nbsp;


When the `counter` function is called using `counter(3)`, an instance of the `increaseCount` function is created that has access to the `count` variable. `step` is set to 3, it's the function parameter variable, and `count` is set to 3 (`count += step`). It is stored in the variable `add3`. When the `counter` function is called again using `counter(5)`, a new instance of `increaseCount` is created that has access to the `count` variable of this new instance. `step` is set to 5 and `count` is set to 5 (`count += step`). It is stored in the variable `add5`. Calling these different instances of the closure increments the value of `count` in each instance by the `step` value. The `count` variables in each instance are independent.  Changing the variable value in one closure does not effect the variable values in other closures.


&nbsp;


## A more technical definition of a closure

A closure is when a function remembers and has access to variables in its lexical / outer scope even when the function is executed outside of its lexical scope. Closures are created at function creation time. Variables are organized into units of scope, such as block scope or function scope. Scopes can nest inside each other. In a given scope, only variables in the current scope or at a higher / outer scope are accessible. This is called lexical scope. Lexical, according to the dictionary definition,  means relating to the words or vocabulary of a language. In this case, you can think of it as how scoping occurs in the JavaScript language. Lexical scoping uses the location of where a variable is declared in the source code to determine where the variable is available in the source code. Scope is determined at compile time, more specifically lexing time, by the compiler of the JavaScript Engine used to process and execute the code. The first stage of compilation involves lexing / parsing. Lexing is when the code is converted into tokens, which is part of the process of converting code into machine readable code. You can read about how the JavaScript engine works in this article: [JavaScript Visualized: the JavaScript Engine](https://dev.to/lydiahallie/javascript-visualized-the-javascript-engine-4cdf). 


---
&nbsp;

## Why are closures important? Some examples

Here are a few examples of where closures are used in JavaScript and React.


&nbsp;

### JavaScript

#### Async code

Closures are commonly used with async code, for example: sending a POST request using the Fetch API:

```javascript
function getData(url) {
  fetch(url)
    .then((response) => response.json())
    .then((data) => console.log(`${data} from ${url}`));
}

getData("https://example.com/answer");
```

When `getData` is called, it finishes executing before the fetch request is complete. The inner function `fetch` closes over the `url` function parameter variable. This preserves the `url` variable.  

&nbsp;

#### Modules

The JavaScript module pattern is a commonly used design pattern in JavaScript to create modules. Modules are useful for code reuse and organization.  The module pattern allows functions to encapsulate code like a class does. This means that the functions can have public and private methods and variables. It allows for controlling how different parts of a code base can influence each other. Closures are required for this, for functional modules. Functional modules are immediately invoked function expressions (IIFE).  The IIFE creates a closure that has methods and variables that can only be accessed within the function, they are private. To make methods or variables public, they can be returned from the module function. Closures are useful in modules because they allow module methods to be associated with data in their lexical environment (outer scope), the variables in the module: 

```javascript
var myModule = (function () {
  var privateVar = 1;
  var publicVar = 12345;
    
  function privateMethod() {
    console.log(privateVar);
  }

  function publicMethod() {
    publicVar += 1;
    console.log(publicVar);
  }

  return {
    publicMethod: publicMethod,
    publicVar: publicVar,
    alterPrivateVarWithPublicMethod: function() {
      return privateVar += 2;
    },
  };
})();

console.log(myModule.publicVar); // 12345
console.log(myModule.alterPrivateVarWithPublicMethod()); // 3
myModule.publicMethod(); // 12346
console.log(myModule.alterPrivateVarWithPublicMethod()); // 5
console.log(myModule.privateVar); // undefined
myModule.privateMethod(); // Uncaught TypeError: myModule.privateMethod is not a function
```

&nbsp;

#### Functional programming - currying and composition

Currying a function is when a function that takes multiple arguments is written in such a way that it can only take one argument at a time. It returns a function that takes the next argument, which returns a function that takes the next argument, ... this continues until all of the arguments are provided and then it returns value. It allows you to break up a large function into smaller functions that each handle specific tasks. This can make functions easier to test. Here is an example of a curried function that adds three values together:

```javascript
function curryFunction(a) {
  return (b) => {
    return (c) => {
      return a + b + c;
    };
  };
}
console.log(curryFunction(1)(2)(3)); // 6
```

&nbsp;

Composition is when functions are combined to create larger functions, it is an important part of functional programming. Curried functions can be composed into large, complex functions. Composition can make code more readable because of descriptive function names. The following is a simple example of currying and composition where there are two number functions (for simplicity): `five` and `six` that use the `n` function, which allows them to be called alone or composed with other functions such as the `plus` function. The `isEqualTo` function checks if two numbers are the same. 

```javascript
var n = function (digit) {
  return function (operator) {
    return operator ? operator(digit) : digit;
  };
};

var five = n(5);
var six = n(6);

function plus(prev) {
  console.log('prev = ', prev); // prev = 6
  return function (curr) {
    return prev + curr;
  };
}

function isEqualTo(comparator) {
  console.log('comparator = ', comparator); // comparator = 5
  return function (value) {
    return value === comparator;
  };
}

console.log(five()); // 5

// values calculated from the inside to the outside
// 1. six() => result1
// 2. plus(result1) => result2
// 3. five(result2) => final result
console.log(five(plus(six()))); // 11
console.log(isEqualTo(five())("5")); // false
```

&nbsp;


You can read more about currying and composition in this article: [How to use Currying and Composition in JavaScript](https://www.freecodecamp.org/news/how-to-use-currying-and-composition-in-javascript).

&nbsp;

Here is an example of a debounce function, from https://www.joshwcomeau.com/snippets/javascript/debounce/,  that returns a function and makes use of a closure, like the counter example that we used earlier:

```javascript
const debounce = (callback, wait) => {
  let timeoutId = null;
  return (...args) => {
    window.clearTimeout(timeoutId);
    timeoutId = window.setTimeout(() => {
      callback.apply(null, args);
    }, wait);
  };
};
```
&nbsp;


Modern front end frameworks/libraries like React make use of a composition model where small components can be combined to build complex components. 

&nbsp;

### React

#### Making hooks

Here is a function that mimics the `useState` hook. The initial value, the state getter, is enclosed in the closure and acts like stored state:

```javascript
function useState(initial) {
  let str = initial;
  return [
    // why is the state value a function? No re-render in vanilla JavaScript like in React.
    // if you just use the value (no function), then change it with the setter function(setState) and then the log value, it will reference a "stale" value (stale closure) -> the initial value not the changed value
    () => str,
    (value) => {
      str = value;
    },
  ];
}

const [state1, setState1] = useState("hello");
const [state2, setState2] = useState("Bob");
console.log(state1()); // hello
console.log(state2()); // Bob
setState1("goodbye");
console.log(state1()); // goodbye
console.log(state2()); // Bob
```

To see a better implementation where the state value is not a function check out the following article - [Getting Closure on React Hooks](https://www.swyx.io/hooks/).

&nbsp;

####  Closures remember the values of variables from previous renders - this can help prevent async bugs 

In React, if you have an async function that relies on props that may change during the async function execution, you can easily end up with bugs if you use class components due to the props value changing. Closures in React functional components make it easier to avoid these types of bugs. Async functions, that use prop values, use closures to preserve the prop values at the time when the function was created. Each time a component renders, a new props object is created. Functions in the component are re-created. Any async functions that use variables from the props (or elsewhere), remember the variables due to closure. If the component that an async function is in is re-rendered and the props change (new values) during the async function call, the async function call will still reference the props from the previous render, where the function was defined,  as the values were preserved due to closure. You can see an example of this in the article -  [How React uses Closures to Avoid Bugs](https://epicreact.dev/how-react-uses-closures-to-avoid-bugs/).

---
&nbsp;

## Conclusion

We learned what closures are using some examples and saw some example use cases in JavaScript and React. To learn more about closures, you can check the articles linked below. 

---
&nbsp;

## References / Further Reading

- [MDN Closures article](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures)
- [You Don't Know JS book - Getting Started - Chapter 3](https://github.com/getify/You-Dont-Know-JS/blob/2nd-ed/get-started/ch3.md)
- [You Don't Know JS book - Getting Started - Appendix B](https://github.com/getify/You-Dont-Know-JS/blob/2nd-ed/get-started/apB.md)
- [Dan Abramov Closure article](https://whatthefuck.is/closure)
- [JavaScript Module Pattern Basics](https://coryrylan.com/blog/javascript-module-pattern-basics)
- [Module Design Pattern in JavaScript](https://www.digitalocean.com/community/conceptual_articles/module-design-pattern-in-javascript)
- [How to use Currying and Composition in React](https://www.freecodecamp.org/news/how-to-use-currying-and-composition-in-javascript/)
- [Getting Closure on React Hooks](https://www.swyx.io/hooks/)
- [How React uses Closures to Avoid Bugs](https://epicreact.dev/how-react-uses-closures-to-avoid-bugs)