How you can learn Closures in JavaScript and understand when to use them
Tags: tutorial, javascript, webdev, beginners
Published: 2020-07-02 19:35:56

---
title: How you can learn Closures in JavaScript and understand when to use them
published: true
description: Learning what Closures are and how to apply them
tags: tutorial, javascript, webdev, beginners
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/175e0rr6ds71e4uqwoub.jpg
---

Follow me on [Twitter](https://twitter.com/chris_noring), happy to take your suggestions on topics or improvements /Chris

if you are like me, you hear concepts like *lexical environments*, *closure*, *execution context* and you're like yep I heard it, can't remember what they are but I'm probably using it. And you know what, you'd be correct. You are most likely using it but who can remember these terms anyway?

I mean most likely the only time we need to know what the name of these terms is, is when we need to study up for an interview in JavaScript. I'm not saying don't learn the concepts, I'm saying as long as you know how they work the world won't implode if you call them something else:

![Bear claw](https://dev-to-uploads.s3.amazonaws.com/i/40rftzuqi2dp68gtypyc.jpg)

We know that we need to know these terms at the point of the interview, the rest of the time we just need to know how things work when we code, and we do.

Let's dig deeper, how come we can understand and even apply these terms but not know what they are called? Is it bad naming? Maybe, in my case, it's about realizing I'm a visual learner and I need an image to remember things by, or it doesn't stick.. 

> So welcome to a crazy ride into my brain - let's talk Closures :)  - All aboard the crazy train ;) ![Crazy train](https://dev-to-uploads.s3.amazonaws.com/i/5lp50cyfqslwzolkwbz5.gif)

## Closures

What are closures? Closures are a function bundled with its lexical environment.

> Thank you professor but I barely understood a word 

Ok, let's look at some code:

```javascript
function outer() {
  // lexical environment
  let a = 1;
  return function inner(b) {
    return a + b
  }
}
```

What you are seeing above is a function `outer()` *enclosing* another function `inner`. It's not only *enclosing* `inner()` but also the variable `a`.

> What's so great about this?

Even after the function `outer()` has stopped executing the function `inner()` will have access to its lexical environment, in this case, the variable `a`.

> *Lexical environment*, sounds like lexicon, huge and heavy books. Show me.

Ok, imagine we call the code like this:

```javascript
const fn = outer();
fn(5) // 6
```

Above it *remembers* `a` to have value `1`.

> Ok, so it's like it treats `a` as a private variable, but in a function?

Yea, precisely.

> I have an idea how to remember this :)

Yes?

> Cows

Cows?!

> Yes Cows in an enclosure with the outer function as the enclosure and the cows as the inner function and the private variable, like this:

![Cows in an enclosure](https://dev-to-uploads.s3.amazonaws.com/i/3ly0le57qb9zizttejwb.png)

Oook, slooowly stepping away.

## What can we use them for

Ok so we got some intro to closure, but let's state what we can use them for:

- **Creating private variables**, we can create a lexical environment long after the outer function has finished executing, this enables us to treat the lexical environment as if it were private variables in a class. This enables us to write code like this:

   ```javascript
   function useState(initialValue) {
     let a = initialValue;
     return [ () => a, (b) => a = b];
   }

   const [health, setHealth] = useState(10);
   console.log('health', health()) // 10
   setHealth(2);
   console.log('health', health()) // 2
   ```

   Above we see how we return an array that exposes methods both for returning and setting the variable `a` from the lexical environment

- **Partial application**, the idea is to take an argument and not apply it fully. We've shown that in our very first example but let's show a more generic method `partial()`:

  ```javascript
  const multiply = (a, b) => a * b;

  function partial(fn, ...outer) {
    return function(...inner)  {
      return fn.apply(this, outer.concat(inner))
    }
  }

  const multiply3 = partial(multiply, 3);
  console.log(multiply3(7)) // 21
  ```

  The above code collects all the arguments for the first function `outer` and then it returns the inner function. Next, you can invoke the return value, as it is a function, like so:

  ```javascript
  console.log(multiply3(7)) // 21
  ```

  > Ok, I get how this works I think. What about an application, when do I *actually* use it?

  Well, it's a bit of an academic construct, it's definitely used in libraries and frameworks though.

  > That's it?

  I mean, you can make functions more specialized using it.

  > Just one example?

  Sure, here is one:

  ```javascript
  const baseUrl = 'http://localhost:3000';

  function partial(fn, ...args) {
      return (...rest) => {
        return fn.apply(this, args.concat(rest))
      }
  }

  const getEndpoint = (baseUrl, resource, id) => {
      return `${baseUrl}/${resource}/${id ? id: ''}`;
  }

  const withBase = partial(getEndpoint, baseUrl);
  const productsEndpoint = withBase('products')
  const productsDetailEndpoint = withBase('products', 1)

  console.log('products', productsEndpoint);
  console.log('products detail', productsDetailEndpoint);
  ```

  The above is quite a common scenario, constructing a URL endpoint. Above we create a more *specialized* version with `withBase` that is partially applying the `baseUrl`. Then we go on to add the specific resource idea like so:

   ```javascript
   const productsEndpoint = withBase('products')
   const productsDetailEndpoint = withBase('products', 1)
   ```

   It's not a thing you *have to* use, but it's nice and can make your code less repetitive. It's a pattern.

- **Isolate part of your code/pass the JavaScript interview**, for this one let's first show a problem that is very common in JS interviews. I got the same question asked to me in three interviews in a row. The question can also be found if you Google it. Cause guess what, that JavaScript interview process is broken.

   > What do you mean broken?

   Nobody cares if you have many years of experience doing this and that and knows a bunch of frameworks. Instead, the interviewers usually spend 5 minutes googling JavaScript questions to ask you.

   > Sounds like they are asking about the JavaScript language and it's core concepts. Isn't that good?

   Yea that part is good, but JavaScript has so much weirdness to it there's a reason Crockford wrote a book called JavaScript the good parts, and that it's a very thin book. There are definitely good parts to it but also a lot of weirdness.

   > You were going to tell me about an interview problem?

   Right, so here's the code, can you guess the answer?

   ```javascript
   for (var i = 0; i < 10; i++) {
    setTimeout(() => {
      return console.log(`Value of ${i}`);
    }, 1000)
   }  
   ```

   > 1,2,3,4,5,6,7,8,9,10

   Not hired.

   > That's cold, can you tell me why?

   `setTimeout` is asynchronous and is called after `1000` milliseconds. The for-loop executes right away so that by the time `setTimeout` is called the `i` parameter will have it's maximum value `10`. So it prints `10`, `10` times. But we can fix it so it prints it in an ascending way.

   > How?

   By creating a scope, an *isolation* in the code, like so:

   ```javascript
   for (var i = 0; i < 10; i++) {
     ((j) => setTimeout(() => {
      return console.log(`Value of ${j}`);
    }, 1000))(i)
   }
   ```

   The above creates an **I**mmediately **I**nvoked **F**unction **E**xpression, IIFE (It does look iffy right ;) ? ). It accomplishes isolation whereby each value of `i` is bound to a specific function definition and execution.

   There is an alternative to the above solution, using `let`. The `let` keyword creates a *scoped* code block. So the code would instead look like so:

   ```javascript
   for (let i = 0; i < 10; i++) {
    setTimeout(() => {
      return console.log(`Value of ${i}`);
    }, 1000)
   }  
   ``` 

   Thank you Quozzo for pointing this out. 

## Summary

> Ok, so this whole closure business is about Cows and fences and privacy

And JavaScript ;)