JavaScript Closures, and How They Work
Tags: javascript, beginners
Published: 2019-01-17 19:17:23

---
title: JavaScript Closures, and How They Work
published: true
tags: JavaScript,Beginner
canonical_url: https://carlanderson.xyz/javascript-closures-and-how-they-work/
cover_image: https://images.unsplash.com/photo-1484814915025-858e00100866?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=1080&fit=max&ixid=eyJhcHBfaWQiOjExNzczfQ
---

Closures, as well as being a favourite interview question, are one of the more confusing parts of JavaScript.

Despite the wealth of articles offering explanations of closures, there are dozens of threads on reddit and other forums asking for more help with closures. It's not hard to see why, since most explanations of closures come out looking like this:

> _Imagine you have a backpack._   
> _Inside that backpack there is a folder, a lunchbox, and some mail._   
> _Inside the lunchbox, there is also an apple._   
> _Suddenly, all of these items come to life and try to take stuff from each other, breaking this analogy._   
> _Luckily, because of closures, some of them can't._   
> _The end._

Closures are a fundamental part of JavaScript that every serious programmer should know inside out - and once you remove the lunch-based explanations - if you have a basic understanding of scope - mastering closures is easy!

This article is going to cover exactly what a closure is, how to use them, and why you should care.

## What is a closure anyway?

To put a long story short: _closures are functions._

That's it. Honestly. Obviously, they are a little bit more complex than that, otherwise we wouldn't have bothered to give it a special name.

The concept of closures exist because of one rule we have in Javascript: **Inner scopes are able to access everything in parent scopes.** Since functions create a new scope, this can become: "Every function has access to variables and parameters from its parent functions."

The detailed explanation is that _closures are an implementation detail of Javascript_ – In order to ensure variables from parent scopes _remain_ in scope, functions need to keep references to them. **A closure is the combination of a function and the scope the function has stored.**

What closures means for a developer is that any function I create will only reference the scope where it was defined, no matter where the function is actually called.

## How are we meant to use closures?

The truth of closures is that you very rarely need to "use" them explicitly. They form a core part of how functions handle scope, so you tend to use them without ever needing to think about it.

A common example of a closure in action you might be familiar with is _callbacks._

```javascript
//foo.js
import {sillyConcat} from './bah.js';

const globals = {};

sillyConcat('hello', 'world' , function(result) {
    //This function creates the closure, and includes a reference to globals
    globals.hello = result;
});

//bah.js
function sillyConcat(s1, s2, callback) {
	//This is where the closure is called - there is no direct access to
	//variables from foo.js, but the function runs fine anyway
	callback(s1 + s2);
}

export {
	sillyConcat: sillyConcat
};
```

## Why do we need to know about closures?

For the most part, you don't. _Except when you do_. It can be important to know _how_ functions store references to variables in parent scopes to avoid bugs and some tricky gotchas.

This is a common gotcha that involves closures (and can be an interview question).

```javascript
function delayedPrint() {
	let total = 0;
	for (let i = 0; i < 4; i++) {
        total += i;
		setTimeout(function closure() {
			console.log(total);
    	}, 200);
	}
}

delayedPrint(); //expected: 0, 1, 3, 6 actual: 6, 6, 6, 6
```

This happens because each of our `setTimeout` functions takes a reference to the `total` variable, but doesn't check its value. By the time the function is called, the loop has finished running, and `total` equals 6 – so each function prints `6`.

To get around this, we need to copy the value of `total` to a new variable that isn't stored in the parent scope. We can do this by passing it as a parameter to the function.  

```javascript
function delayedPrint() {
	let total = 0;
	for (let i = 0; i < 4; i++) {
        total += i;
		setTimeout(function closure(total) {
			console.log(total);
    	}, 200, total);
	}
}

delayedPrint(); //expected: 0, 1, 3, 6 actual: 0, 1, 3, 6
```

We could also achieve this by creating another function and calling it immediately (an IIFE).

```javascript
function delayedPrint() {
	let total = 0;
	for (let i = 0; i < 4; i++) {
        total += i;
        (function(total) {
        	setTimeout(function closure() {
				console.log(total);
    		}, 200);
        })(total);
	}
}

delayedPrint(); //expected: 0, 1, 3, 6 actual: 0, 1, 3, 6
```

If you're interested in learning more about closures, MDN has a [great article](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures).

If you found this article helpful, [consider joining my newsletter](https://pages.convertkit.com/de362bddba/e411d0e335).