2 Examples To Help You Understand JS Closures Once And For All 🙃
Tags: beginners, codenewbie, javascript, tutorial
Published: 2020-02-07 12:33:11

---
title: 2 Examples To Help You Understand JS Closures Once And For All 🙃
published: true
description: Closures can seem confusing, but they don't need to. This tutorial will try to clear things up. 
tags: beginners, codenewbie, javascript, tutorial
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/idgj8l390t97y2tw9o4d.jpg
canonical_url: https://www.daysof.dev/javascript/examples-to-understand-javascript-closures/
---

*If you find this post useful, you can follow me on [twitter](https://twitter.com/_twosmalltrees), sign up to my [mailing list](https://www.twosmalltrees.com/mailing-list) or check out the other posts on my [blog](https://www.twosmalltrees.com). I've also got a couple of active side projects that you might like to check out:*

* *[ippy.io](https://www.ippy.io) - An app for creating beautiful resumes*
* *[many.tools](https://many.tools) - A collection of useful utilities for designers and devs*

<hr />

Closures are one of the classic “gotchas” in JavaScript. There are countless articles  across the internet describing closures as something you absolutely need to understand to consider yourself a competent developer, or must know before your next job interview, etc etc.

Don’t get me wrong, understanding closures **is** very important. The thing is, I think there’s a reasonable chance you already understand them, but just don’t understand that you understand them 😉. But if you don’t, hopefully you will soon. 

It’s just a hunch, but my guess is that a fair bit of the confusion around closures is simply due to terminology. That is, it can take some time to connect unfamiliar words like **”closure”** and **“lexical scope”** with behaviour you’ve observed and perhaps already understand in your code.

Let’s take a look at a relatively straightforward example to test your current understanding.

<hr />

## 1. Counter

Take a look at the code below, and try to figure out the answers to the two commented questions (without running the code).

```js
function createCounter() {
  var count = 0
  function getNext() {
    count ++
    return count
  } 
  return getNext
}

console.log(count)
// ==> 1. What will this output?

const getNextNumber = createCounter()

const firstNumber = getNextNumber()
const secondNumber = getNextNumber()
const thirdNumber = getNextNumber()
const fourthNumber = getNextNumber()

console.log(
  firstNumber,
  secondNumber,
  thirdNumber,
  fourthNumber
)
// ==> 2. What will this output?

```

If you answered:

  1. ReferenceError (or if you knew this would be some kind of error)
  2. 1, 2, 3, 4

Congratulations! You understand closures!

There are two things you need to grasp from the code above:

  1. The `count` variable **is not** accessible anywhere outside of the `createCounter()` function.
  2. The `count` variable **is** accessible to any functions that are declared **within** the `createCounter()` function (where it was initially declared).

This is all that a closure is. Using a function (in our case `createCounter()` ) to **close over** a variable. 

There is no way for the `count` variable to be accessed or set from anywhere else in our code, **except** via the function that we define and return from `createCounter()`, the `getNext()` function. 

As you can see, `getNext()` (since it was declared inside `createCounter()`) maintains access to the `count` variable, and is able to increment and return it.

Let’s take a look at a slightly more complex example.

<hr />

## 2. Election Day

Imagine we’ve been tasked with running an election. It’s a somewhat odd election, as voters will be casting their ballots from our JavaScript console.

We want a way to:
 
  1. Keep track of the votes
  2. Allow people to cast votes
  3. Retrieve the final results (in a secure, password protected way)

We could do something like this (but shouldn’t):

```js
var candidateOneVoteCount = 0
var candidateTwoVoteCount = 0

function voteForCandidateOne() {
  candidateOneVoteCount ++
}

function voteForCandidateTwo() {
  candidateTwoVoteCount ++
}

function getResults(inputPassword) {
  if (inputPassword !== "password123") {
    throw new Error("Wrong password")
  }
  return {
    candidateOne: candidateOneVoteCount,
    candidateTwo: candidateTwoVoteCount
  }
}
```

Since the variables storing the candidates votes are defined in the global scope, anyone casting their vote could sneakily rig our election simply by running `candidateTwoVoteCount = 1000000`.

We need to keep our vote counts private. We only want it to be possible to change or retrieve these variables via the interface that we’ve defined.  That is, via:
- `voteForCandidateOne()`
- `voteForCandidateTwo()` 
- `getResults()`

How can we achieve this? With a **closure**.  Let’s refactor the code above to use a closure.

```js
function createElection(password) {
  var candidateOneVoteCount = 0
  var candidateTwoVoteCount = 0

  function voteForCandidateOne() {
    candidateOneVoteCount ++
  }

  function voteForCandidateTwo() {
    candidateTwoVoteCount ++
  }

  function getResults(inputPassword) {
    if (inputPassword !== password) {
      throw new Error("Wrong password")
    }
    return {
      candidateOne: candidateOneVoteCount,
      candidateTwo: candidateTwoVoteCount
    }
  }

  return { 
    voteForCandidateOne, 
    voteForCandidateTwo, 
    getResults 
  }
}

const {
  voteForCandidateOne, 
  voteForCandidateTwo, 
  getResults 
} = createElection("password123")


console.log(candidateOneVoteCount)
// ReferenceError

console.log(candidateTwoVoteCount)
// ReferenceError

console.log(getResults("incorrectPassword"))
// Error: Wrong password

console.log(getResults("password123"))
// => { candidateOne: 0, candidateTwo: 0 }

voteForCandidateOne()
voteForCandidateOne()
voteForCandidateTwo()

console.log(getResults("password123"))
// => { candidateOne: 2, candidateTwo: 1 }

// Please never run a real election using code like this.
```

Our interface functions `voteForCandidateOne()`, `voteForCandidateTwo()` , `getResults()` are now declared within, and returned from `createElection()`. As they are declared in the same scope, they maintain access to the variables storing the vote count (`candidateOneVoteCount` & `candidateTwoVoteCount`).

It’s also worth noting that the functions also maintain access to the `password` argument that is provided when `createElection()` is called. This is later compared to the password provided in `getResults()` to validate access.

<hr />

Let me know if anything here is unclear, and I'll do my best to explain it further! 🍻