Image for post
Image for post

Closures in JavaScript

Vakhtang Nodadze
Nov 27, 2020 · 5 min read

Closures are often a mystery to many people. Many of them don’t even know it exists, many of them don’t understand it fully and many of them use it without even knowing about it. I was among those as well. But coding in Javascript without understanding how closures work is like talking to a person in English and not knowing grammar. You will probably be able to get the point across but not very elegantly so say it softly.

So what exactly is a closure?

A closure is the combination of a function bundled together (enclosed) with references to its surrounding state (the lexical environment). In other words, a closure gives you access to an outer function’s scope from an inner function. In JavaScript, closures are created every time a function is created, at function creation time. Closure means that an inner function always has access to the parameters of its outer function, even after the outer function has returned. The outer function can very well be the global scope. For example:

The sumTwoNumbers function has access to the globalScopreVariable without it passing to it. This happens because Javascript has a lexicon scope.

Image for post
Image for post

Different closure examples

I’m a strong advocate of learning by examples, so let’s go through a couple of examples and explain how they work and why they work the way they do.
let’s wrap our previous code in a block.

In this case, our program won’t execute and give out an error: ReferenceError: sumTwoNumbers is not defined. This happens because our sumTwoNumbers function is now declared locally and cannot be accessed from outside the block. (the new ES6 const and let declarations are block scoped, unlike the previous var which was function scoped). So what can we do now? well, we can declare the sumTwoNumbers function outside the if block and than assign the values we want.

The one above all

This all seems pretty easy, right? Let’s examine one more code and try to explain it.

Can you guess what this code will print? Let’s go through it together.

1. Line 1 we create an outer function and inside create a local variable, assigning it 3. After that, we create a new local function and inside it, we increment the outer function’s variable and return it. Closing that function we return the whole function itself.

So basically, we have a function that returns another function, which in itself accesses and changes the variable inside the container function. Feeling dizzy already?

2. On line 9 we create a new variable in the global scope and assign it the container function. So now, our increment variable now contains the value of whatever counter function is returning. Since we already said that it returns another function, we can execute it.

3. Line 10, 11, and 12 are calling that variable, which in of itself, is calling the counter function.

4. We know calling the c1 which increment the counter which is 0 by one and return that. So c1 should be 1.

5. Same is done for c2 and c3, they execute the counter function, incrementing the local variable and returning 1, right?

NO.
If you run the code, you will see that it logs, 1,2, and 3. So what the hack? The count variable is local scoped, right? if you try to print it out, it will give you undefined, so how do the next functions know its previous value? This is where closures come in.

Here is how it works. Whenever you declare a new function and assign it to a variable, you store the function definition, as well as a closure. The closure contains all the variables that are in scope at the time of the creation of the function. It is analogous to a backpack. A function definition comes with a little backpack. And in its pack, it stores all the variables that were in scope at the time that the function definition was created.

So now we understand how this works. The key to remember is that when a function gets declared, it contains a function definition and a closure. The closure is a collection of all the variables in scope at the time of creation of the function.

Remember, all functions create a closure but as we saw it the first and second examples, it isn’t too difficult to wrap your head around it, hack it’s not even much relevant. BUT… when your function returns another functions, that is where closures become much more relevant and a bit more complicated.

Think you now understand closure? Cool. Glad to be of service.
Before you go, let’s put your knowledge to the test.

Do you know what this code will print and more importantly WHY?
The what question might be an easy one since there are only two numbers, yes, It’s 12. But do you understand why?

The a is a global variable, right? That’s an easy one. But what are we doing with the adder variable and then the answer variable? When we create the adder variable and pass 4 to it, that becomes the x argument. So the adder function now returns the inside function, so passing the a variable will register as the inside functions argument.

The variable a is part of the closure. When the variable adder gets declared in the local scope, it is assigned a function definition and a closure. The closure contains the variable x. So now when adder is called and executed, it has access to the variable x from its closure and the variable y which was passed as an argument and is able to return the sum.

Conclusion

Probably the best explanation I’ve heard about closures is the backpack analogy. When a function gets created and passed around or returned from another function, it carries a backpack with it. And in the backpack are all the variables that were in scope when the function was declared.

Enjoyed this article? If so, get more similar content by subscribing to our YouTube channel!

New JavaScript + Web Development articles every day.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store