Closures in Javascript
Tags: javascript
Published: 2019-02-18 18:23:44

---
title: Closures in Javascript
published: true
description: Let's explain what closures are!
tags: javascript
---

## Introduction

You may have heard about closures. You most certainly already use them even if you don't fully know what they are. Closures require you to know:


# Three facts:

#### Fact One: In Javascript, you can refer to variables defined outside of the current function.

```javascript
function makeCookies(){
	const secretIngredient = "coconut oil"
	function bake(chocolate){
		return secretIngredient + " and " + chocolate
	}

	return bake("white chocolate")
}

makeCookies() // coconut oil and white chocolate
```

Here, we can see that the inner function *bake* can access the variable *secretIngredient*, even though it was defined in the outer *makeCookies* function.

#### Fact Two: Functions can refer to variables defined in outer functions even **after** those outer functions returned!

Because functions are first-class objects, you can store functions inside variables and call them later on. I've talked about higher-order functions in a [https://dev.to/damcosset/higher-order-functions-in-javascript-4j8b](previous article)

```javascript
function cookiesMaker(){
	const secretIngredient = "coconut oil"
	function bake(chocolate){
		return secretIngredient + " and " + chocolate + " chocolate."
	}

	return bake
}

const func = cookiesMaker() // Storing the function in a variable
```

Here, *cookiesMaker* is called and we store the result of that function inside a variable. If you print out the *func* variable right now, you would see the *bake* function.

The *bake* function uses a variable declared outside of the *bake* function (*secretIngredient*). The *bake* function can **still** remember that variable even if *cookiesMaker* has already returned.

```javascript
func("black") // coconut oil and black chocolate.
func("white") // coconut oil and white chocolate.
```

How is this possible? Well, in Javascript, function values do not just store the code required to execute when they are called. They also store any references to variables they need to execute. Functions like the *bake* function, who refer to variables declared in their containing scopes are known as **closures**. 

The *bake* function here keeps track of two variables declared in its containing scope: *secretIngredient* and *chocolate*.

When we call *bake* afterwards, it still remembers those two variables because there were stored in the closure.

A closure can refer to any variable or parameter in its scope. Check this out:

```javascript

function cookiesBaker(cook){
	return function addSecretIngredient(secretIngredient){
		return function bakeCookie(chocolate){
			return `${cook} cooked a ${secretIngredient} ${chocolate} chocolate cookie.`
		}
	}
}
```

In this example, the inner function *bakeCookie* refers to a parameter from the outer *cookiesBaker* function (*cook*), a parameter from the outer *addSecretIngredient* function (*secretIngredient*) and a parameter from its own scope (*chocolate*).

```javascript
const cook = cookiesBaker("Damien")

const secret = cook("peanut butter")

const result = secret("white")
// Damien cooked a peanut butter white chocolate cookie.
```

Here, we are taking one more step. 

We return the inner function *addSecretIngredient* and store that in a variable. Then, we call that stored function, the result ( *bakeCookie* ) is stored inside another variable. Finally, we call that function. The final results, as you can see, remembers all the variables stored inside the closure.

We can also use this to make more general-purpose functions.

Let's say we want to create a function for all cookies baked by Johnny:

```javascript
const bakedByJohnny = cookiesBaker("Johnny")

bakedByJohnny("coconut oil")("black") // Johnny cooked a coconut oil black chocolate cookie.

bakedByJohnny("")("milk") // Johnny cooked a  milk chocolate cookie.
```

Notice that instead of declaring a variable and storing the intermediate function inside it. I can call the inner function immediately because *bakedByJohnny("coconut oil")* is returning a function!

Ok, another little example. Let's create a function for all cookies baked by Sarah with peanut butter:

``` javascript
const bakedBySarahPeanutButter = cookiesBaker("Sarah")("peanut butter")

bakedBySarahPeanutButter("white")
//Sarah cooked a peanut butter white chocolate cookie.

bakedBySarahPeanutButter("black")
// Sarah cooked a peanut butter black chocolate cookie.

bakedBySarahPeanutButter("milk")
// Sarah cooked a peanut butter milk chocolate cookie.
```

Even though the two functions we created come from the same function definition, they are two distinct objects and both store different variables.

*Note*: The functions can be anonymous, like so:

```javascript
let cookiesBaker = function(cook){
	return function(secretIngredient){
		return function(chocolate){
			return `${cook} cooked a ${secretIngredient} ${chocolate} chocolate cookie.`
		}
	}
```

This code would give the exact same results than before!

#### Fact Three: Closures can not only remember the variable in their containing scope, they can also **update** it.

Consider the following example:

```javascript
const secretIngredient = function(){
	let ingredient = undefined
	return {
		changeIngredient: newIngredient => { ingredient = newIngredient },
		showIngredient: () => ingredient,
		type: () => typeof ingredient
	}
}
```

This function returns 3 closures. Each method in the object returned refer to a variable defined in the containing scope.

Now, let's prove that closures can not only read outer variables, they can also update them:

```javascript
let i = secretIngredient()

i.showIngredient() // undefined
i.type() // undefined

i.changeIngredient("coconut oil")

i.showIngredient() // coconut oil
i.type() // string

```

Tadaaaaa!

# Conclusion

Closures are one of those things that you most likely use very often. You probably didn't even know about it! Check your code and try to identify closures, get comfortable with them, and use their full powers!