JavaScript Closures
By: Alexandra Ortiz
Tags: Closure, Coding Interviews, JavaScript

As a recent graduate of the Flatiron School, I am now embarking on the exciting adventure of landing my first job as a web developer. As I study, research, and prepare for technical interviews, I’ve noticed a theme emerging: JavaScript closures are a must know!

Defining a Closure

I’m not going to lie, when I first started reading about closures I was having a hard time really wrapping my head around the concept. The definitions seemed easy enough when I combed through all of the “Top X Things to Know for a Technical Interview”, but when I was finally asked to define what a closure was in my first interview, I froze. I’ll blame a small portion of my paralysis on nerves, but the main issue was that I was still very confused about what closures were at their core and why they are fundamental to JavaScript.

So enough jabber, let’s get to the actual definition of a closure. According to the MDN web docs, a closure is defined as the following:

“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.” — MDN web docs

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures

Another great definition comes from Kyle Simpson, author of “Scopes and Closures” which does an amazing job of breaking down both topics.

“Closure is when a function is able to remember and access its lexical scope even when that function is executing outside its lexical scope.” — Kyle Simpson, Scopes and Closures

Another way to think about it — and likely a picture you won’t forget — is to think of closures as a pregnant woman and her unborn baby. Once the baby is born, it still has access to its mom’s DNA even though it is no longer inside the womb. Similarly, a nested function in a closure still has access to its lexical scope, or environment, even after the parent function has finished executing.

Created by the author using Kapwing meme generator.

So now that we’ve established what closures are, let’s take a look at some closures in action.

Understanding Scope

As we stated before, the two main components of a closure are the lexical scope and a function. When talking about scope in programming, what we are really hitting at is access. Scope means access, so when something is in scope, we have access to it. When something is out of scope, we do not have access to it.

In JavaScript, functions have access to their parent’s environment, or outer scope, and to the local scope they create inside themselves. Let’s take a look at the code below to see how scope changes for nested functions.

Screenshot illustrates how scope changes as functions are nested. Screenshot by author.

In the case of the addMore function, it has the widest scope, allowing it to access the variables in:

its own scope, z = 20 ;

; its parent’s scope, y = 10 ;

; and the global scope where x = 5 .

You can also see that when we try to console.log the variables, we are only able to get the value for x while y and z will render reference errors. Interestingly, when we render to the console makeAdder()() , we get the value of 35 which is what you would expect when adding x+y+z together, as we did in the addMore function. And that is the closure! Let’s break it down one more time to make sure we understand what is going on.

The reason we invoke makeAdder()() with two sets of parenthesis is because the first set is invoking makeAdder() which returns the function addMore . By adding the second set of parenthesis, we are invoking the returned function and thus able to get 35 . This is because the function addMore is enclosed with its surrounding state (lexical scope) and is able to access those references (variables) at a later time.

Closures as a Function Factory

Let’s take a quick look at another example of a closure.

Screenshot by author.

In the code above, we have parentFunc which takes in an argument and returns another function, childFunc , which itself requires an argument for the variable y .

In this closure example, we didn’t define the variable x inside of the parentFunc function but in line #7 where we passed in 5 as our argument. The real magic happens in lines #9 and #10 where we use our multiply5 variable with the additional y argument to get 10 and 15 , respectively.

This is a closure because the nested function, returned when multiply5 is invoked, retains the reference to its state even after its parent function has finished executing. We can even check in our browser console to see what the closure entails by using console.dir(multiply5) .

When we use console.dir, we can see the closure of our parentFunc along with the state.

Conclusion

Closures are an essential fundamental of JavaScript and likely to pop up over and over again, especially during technical interviews. The examples above are just the tip of the iceberg and fairly simple examples of what closures are used for. If you’ve ever written an app that has a counter or even used Redux, chances are you have been doing this all along. I highly recommend digging into some of the resources I used below to get a more advanced and in-depth look at this fundamental topic.