JavaScript Bites: Closure
Tags: beginners, javascript, programming, webdev
Published: 2021-11-16 00:18:54

---
title: 'JavaScript Bites: Closure'
description: 'The concept of a closure in JavaScript can be confusing at first, this article sheds light on what it means!'
tags: 'beginner, javascript, programming, webdev'
published: '2021-11-15'
canonical_url: https://www.catstache.io/blog/javascript-bites-closure
series: JavaScript Bites
---

> **TLDR:** Closure is the concept of storing a function and its environment together.  When you create a function, it stores the functions local environment and its outer environment together.  If you are ever confused about what value will be present, understand what value existed when the function scope was created!

## Formal Definition

If you were to look up what a closure is, [Wikipedia's definition](https://en.wikipedia.org/wiki/Closure_(computer_programming)) has this to say in the first two lines:

> In programming languages, a closure, also lexical closure or function closure, is a technique for implementing lexically scoped name binding in a language with first-class functions. Operationally, a closure is a record storing a function together with an environment. 

That is a bit of a dense definition, but its not a complex as it seems at first glance!  This article aims to explain what this means, bit by bit, so you can use closures with confidence.

## Scoping
I first want to touch on what scoping means in JavaScript.  Before ES6, JavaScript only had **Global Scope** and **Function Scope**.  You have probably seen how variables are accessible based on what scope they were declared in.  Here is an annotated example:

```javascript
// Variable declared at the global scope.
var globalVariable = 'Neat';

function func() {
  // Variable declared in function scope.
  var funcVar = 12;

  console.log(globalVariable);
}

console.log(funcVar);
func();
```

If you were to execute the above code, you would get a `ReferenceError: funcVar is not defined` error.  If you remove the `console.log(funcVar);` line, the output would be `Neat`.  The reason for this is that scopes can only reference variable declared in their own scope (local) and any outer scopes relative to the current scope.  In this case, the scope in `func()` can access the outer scope (global) to get the value of `globalVariable`, however the global scope does not have access to the scope created for `func()` so it cannot access the funcVar variable.  One more example to show how inner scopes can access values in outer scopes.

```javascript
var globalVar = 'Hello';

function func() {
  var innerVar = 'World';

  function innerFunc() {
    var name = 'innerFunc';

    console.log(`${globalVar} ${innerVar}, from ${name}`);
  } 
  innerFunc();
}

func();
```

Executing the above will show `Hello World, from innerFunc` in the console.  We can see that `innerFunc()` has access to its local scope, the scope of `func()` and the global scope.

## Closure
The example above is actually a closure!  It represents the second part of the Wikipedia definition, `Operationally, a closure is a record storing a function together with an environment.`  In this case, the function is `innerFunc()` and the environment that is being stored is the local scope along with all of the outer scopes present at the time of function creation.

Thats it!  If you have been writing functions, you have been creating closures this whole time!

## Whats the Big Deal
The reason this can be a confusing topic is that closures can enable a handful of different patterns and ideas in JavaScript, even if they don't seem related at all.  So here are some quick examples of things that are possible because of closures:

### Access Data Through Interface
Say you wanted to create a simple counter with a variable representing the current count, and four functions: add, subtract, reset, show.

```javascript
let count = 0;

const add = () => {
  count = count + 1;
};

const subtract = () => {
  count = count - 1;
};

const reset = () => {
  count = 0;
};

const show = () => {
  console.log('Count: ', count);
};
```

If you were to use these functions to add and show, like
```javascript
add();
add();
add();
add();
show();
```

you would get `Count: 4`.  The issue is that if I were to throw in `count = 0;` right before the `show()` it would show `Count: 0`!  We are operating on a variable that any scope can access and modify, since it is global, and that is dangerous.  Something can accidentally mess with count and cause a headache of a bug.  This can be written in a different way:

```javascript
const mkCounter = () => {
  let count = 0;

  const add = () => {
    count = count + 1;
  };

  const subtract = () => {
    count = count - 1;
  };

  const reset = () => {
    count = 0;
  };

  const show = () => {
    console.log('Count: ', count);
  };

  return {
    add,
    subtract,
    reset,
    show
  };
};
```

This code is very similar, but you can see that we have declared it inside of a new function called `mkCounter` that defined the count variable locally to its scope.  At the end, we return an object that exposes the four functions but **not** the count variable, however since all of these functions are defined inside the `mkCounter` scope, the closing environment for all of them contain `count`!  Here is how it would be used:

```javascript
const counter1 = mkCounter();
const counter2 = mkCounter();

counter1.add();
counter1.add();
counter1.add();
counter1.subtract();

counter2.subtract();
counter2.subtract();

counter1.show();
counter2.show();
console.log(counter1.count);
```

which will give the output of:
```
Count: 2
Count: -2
undefined
```

Awesome, so not only can we **not** access the count as shown by the last line, each counter has its own count in their own environment to work with!

### Partial Application
**Edit**: Updated this section thanks to @zaferberkun and @peerreynders in the comments!

Another closure example that I use all the time is partial application.  A simple example could be formatting a log with some data that you don't want to set every time you invoke the function:

```javascript
function logger(route, message, showDate) {
  const header = showDate ? `${new Date().toISOString()} | ${route}` : route;
  console.log(`${header} | ${message}`);
}

function mkLogger(route, showDate = false) {
  // Implement "partial application" with the values
  // in the closure
  return (message) => logger(route, message, showDate);
}

```

Then you can use the function like:

```javascript
const docLogger = mkLogger('DOCS', true);

docLogger('This is my log message');
docLogger('Another log message');
```

with the output of:
```
2021-11-15T23:55:26.672Z | DOCS | This is my log message 
2021-11-15T23:55:26.672Z | DOCS | Another log message 
```

This is nice because you can initialize things like the route and if you want to display the date when the program starts, then pass the simple `docLogger` function to other parts of the application that need to use it instead of calling something like `logger('DOCS', 'This is my log message', false)` every time you want to use it.

### Other Uses
I just wanted to mention some other use cases that you can explore as well: Memoization, Singleton, Event Listeners.

## Conclusion
Hopefully the concept of closure isn't too complex any more!  If you do have any questions please let me know and I will do my best to address them and refine the article for clarity.