Simple Explanation of Javascript Closure

Yasser Hussain
4 min readApr 14, 2017

--

You might be wondering what are Javascript Closures and why you should care about them.

In this post I will attempt to explain what they are and how they can make your life easier by helping you write cleaner code.

But before we do that let us try to build something very common so that we get the big picture about closures.

Let’s build a sequence generator

What’s a sequence generator, you ask?

It is a no-arg function which when called returns the next element of a particular sequence.

For example it could be a natural number generator.

It would work something like this. We will call a function let us say, “next” and we would get the next natural number. Here is a quick demo.

var next = getNaturalNumberGenerator();
next();
1 // returns 1
next();
2 // returns 2
... // and so on

You might be wondering why would we need a function to generate such a simple sequence. The answer is, this sequence is pretty simple but the same idea goes behind building more complex sequences like fibonacci sequence or random number sequences.

Okay so how do build something like this?

One observation we can have here is that the function somehow has to remember its current state, only then can it go ahead and give us the next number, right?

So how we remember states in Javascript? You are right. Objects!!

Here is the code for “getNaturalNumberGenerator”

function getNaturalNumberGenerator() {
return {
counter: 0,
next: function() {
this.counter++
return this.counter
}
}
}

Now all we need to do is call this function and generate sequences. Like so -

var generator = getNaturalNumberGenerator()
generator.next()
1 // returns 1
generator.next()
2 // returns 2

This kinda does what we were trying to achieve only its not pretty. We had to create an object, use “this” keyword and then name the variable “generator” which is completely redundant to our need here.

So is there a better way?

Enter Closure

Closure can really help us clean up our code and do away with all the cruft.

To use closure, we first need to analyse what we did in the previous approach. The essence of that approach was really that we have some executable “code” which is associated with a variable (or “state”) that it looks up and modifies.

This is exactly the kind of thing closure can help us at.

But first things first.

What IS a JS closure?

Simply put, a closure is the ability of a function to remember the environment in which it was created.

So let us write some code to understand the above explanation. The above sequence generator can be re-written this way.

function getNaturalNumberGenerator() {
var counter = 0
return function() {
counter++
return counter
}
}

This is how we run it.

var next = getNaturalNumberGenerator()
next()
1 // returns 1
next()
2 // returns 2

Simple as that. Notice a few things here.

  1. We completely got rid of objects so no crazy “this” keyword is needed here.
  2. Code became more terse and we didn’t need useless variables.
  3. Also notice the key JS feature which made this possible — the ability to return functions just as another variable. (Yay! Functional Programming)

Why does this work?

As I already said JS functions can remember the environment they are created. So even when the interpreter is running the code outside the function, the function itself can get a reference to the counter variable.

Lets take a look again.

function getNaturalNumberGenerator() {
var counter = 0
/*
The below function will always have a handle to
the "counter" variable above. Even when the interpreter
is running code outside of this function.
*/
return function() {
counter++
return counter
}
}

So when we call

next()

the variable “counter” above is updated and we get

1

But what if create two generators like this.

var next1 = getNaturalNumberGenerator();
var next2 = getNaturalNumberGenerator();

Won’t they interfere with one another’s counter variable.

Nope they won’t?

Because each time function “getNaturalNumberGenerator” is called a new environment (or context) is created where the counter value is zero.

And the returned function is associated with environments independent of each other.

So the situation is something like this.

Generator functions with independent counter variables.

Both counter variables are independent of each other and each time we call next we get a next natural number.

So to summarise

Javascript functions are not just code. They have a reference to the environment they were created in, which allows them to access and modify the variables in their scope. This in many cases allows us to write simpler, clearer, more intuitive and readable code.

--

--