Looking for Closure? (Javascript)

Ali Erbay
4 min readJul 23, 2020

--

If you check your ordinary English dictionary you may find the following right next to “closure”;

the feeling or act of bringing an unpleasant situation, time, or experience to an end, so that you are able to start new activities:

Photo by Cristina Gottardi on Unsplash

Well, this is not the closure we are seeking for now. I recently had to go over some intermediate/advanced Javascript concepts to practice and keep my knowledge fresh, I decided to write a medium post about it.

So what are the Closures in Javascript?

Closures in Javascript are nothing but functions with preserved data. A closure is a function that has access to variables defined in an outer function that have previously returned.

So it didn’t sound like it is easy to grasp at first glance, but a code example will make it clearer.

As you can see above, outer function directly returns an anonymous arrow function that returns two string variables and concatenates them. But pay attention to where these outerData and innerData are defined. outerData is in the outer function scope where innerData is in the anonymous arrow function’s scope.

If we invoke outer function, we will get the following;

>> outer()> () => {
let innerData = " and this is inner"
return outerData + innerData
}

Well, this is not surprising, it returns the anonymous arrow function. But notice that this function is making use of outerData variable which was defined in outer function. So let’s go step by step what has happened;

1 - A new variable outerData is created

2 - return returns the entire body of the anonymous arrow function

3 - outer function finishes its execution, and all variables in the function scope, in our case outerData, don’t exist anymore. ( The variables inside the functions only come into existence when the function is running, and cease to exist once the functions complete execution. )

If we invoke the returned function immediately;

>> outer()()> "This is outer and this is inner"

1- A new variable innerData is created

2 - JS will try to get together innerData and outerData in the return. It has information about innerData, because it has just created it. But outerData shouldn’t be there at all, outer function is executed before the inner anonymous arrow function, any variables in the scope of outer function is not defined anymore.

But still, Javascript manages to return two strings together. This simple example showcases an inner function using a variable defined in the outer function even though outer function has already been called before the inner function. This is strange right? The outer function is already returned, its variable definitions don’t exist anymore, how come the inner function can access its variables? This is provided by Closures in Javascript

Let’s see another example,

The inner anonymous arrow function is using variable x which was defined in the outer function and by the time it is called the outer function has returned. Just like the example before, the anonymous arrow function here is a closure.

You can actually see the scope of your function by using console.dir(), use Google Chrome console for this

> k = outer(4)
> console.dir(k)
Notice that Closure Scope has x value as 4

Notes: Inner function needs to be returned by the outer function in order closure to happen and if the inner functions do not use any of outer functions variables, it is just nested function.

So why do we need Closures in Javascript?

The best benefit of using Closures is that it lets us create Private Variables, let’s take a look at the following;

>> let letsCount = counter()
>> letsCount()
> 1
>> letsCount()
> 2
>> letsCount()
> 3
>> count
> Uncaught ReferenceError: count is not defined(...)

If we try to access the starting value count variable defined in the outer counter function, it will return that it is undefined. So nobody can read or edit our Private Variable in this case.

Now head on to a slightly more complex example;

Let’s think this is a function for our weekly grocery shopping, we have a buyList variable which contains the stuff we always buy when we go out for shopping. This is our private variable we have no access to it from outside. Instead of returning one function, we are returning an object with two methods inside they are basically functions anyway.

Now we are going to simulate two different weeks of grocery shopping,

>> let week1 = shoppingList()
>> let week2 = shoppingList()
>> week1.getList()
> ["Milk","Bread","Eggs"]
>> week1.addToList("Onions")
> ["Milk,"Bread","Eggs","Onions"]
>> week2.getList()
> ["Milk","Bread","Eggs"]

As you can see above, any change on the week1 shopping list is not effecting the week2 shopping list because they don’t share the same scope.

Conclusion

We have scratched the surface on JavaScript Closures but the main idea is just like the above. Once you get to know them you will apply them without even realizing you are doing it, it will become second nature to you.

There are two important takeaways from this article;

1- Inner function must use variables defined in outer function scope otherwise it is not a closure

2 - Outer function must return an inner function/or object with methods otherwise it is not a closure

I hope this article comes handy, see you in other articles!

--

--

Ali Erbay

Full Stack Developer BDD/TDD || Ruby on Rails || React || React Native || NodeJS || Express https://github.com/kermit-klein