Quick Wins With Code: Closures in JavaScript

Bobby Tate
The Startup
Published in
3 min readJul 22, 2020

--

What is a closure in JavaScript? Why do closures matter? How do you use closures?

Photo by Pablo Guerrero on Unsplash

Seeing as MDN’s page on closures defines it extremely well, I’m not going to reinvent the wheel here:

A closure is the combination of a function bundled together (enclosed) with references to its surrounding state (the lexical environment).

Let’s unpack this concept a bit.

The first thing I want to point out is that whenever you define a function, you are making a choice about its lexical environment, whether intentional or unintentional, conscious or…maybe you’re unconscious. I don’t know.

In many cases, the lexical environment of a function is just the global scope, because that is where you created it. Don’t worry, there’s nothing wrong with that.

But the value of a closure becomes more obvious when you intentionally enclose a function into its own lexical environment. One of the ways you can do this is by wrapping it inside another function. You’ve now created a more specific, local scope.

Here’s an example:

Here we have a rocket function, which has some local variables, and an inner fly function. When I call rocket, it returns a unique instance of an object with the fly function stored inside that object (line 15). It’s important to note that I’m not actually calling fly yet. I’m just returning an object that has the fly function inside it.

Each time I call the rocket function, I’m returning a separate instance of the fly function, and that instance of fly is actually holding on to its own instance of its lexical environment, even after rocket has completed running.

That right there is the power of a closure: Each time I call rocket, I’m creating an instance of fly that has a persisting reference to a unique lexical environment.

You can see how this specific use case could be valuable if you’re trying to do something object oriented. We’ve encapsulated state and behavior in a persisting, reusable manner! And we didn’t use class, constructor, this, or new. How about that.

One other nice thing about doing object oriented programming in this manner is that your state is actually private and inaccessible compared to when you use class syntax from ES2015. You can’t access the name of a rocket with sputnik._name (unless you added it to the returned object of rocket on line 15, but you shouldn’t do that).

The power to keep private state truly inaccessible is a really good thing. It tells readers how the function should and should not be used. Keep private variables private. This also gives you the option to implement a true “read only” paradigm, if you wanted to.

For example:

I’ve added name access in the object returned by rocket on lines 17–19, using get syntax. I can now read the _name property, but I don’t have the ability to change it. That’s exactly the kind of guardrail that I wanted to implement. Great success!

Sorry for the tangent on private state. I just think it’s one of the cooler things closures make possible.

Here’s one last example of a closure in action:

Here we have a higher-order function (a function that operates on other functions), called moduloFactory. It’s a function that returns other functions, so you could also call it a function factory (thus the word factory in the name).

So where is the closure? In this example, the closure is the combination of the anonymous function returned by moduloFactory (line 2), and the saved lexical environment that this anonymous function keeps in its back pocket, in the form of the argument passed to moduloFactory at the time it was called.

So because of closures, we can pump out as many unique instances of that inner function as we want, and each one will keep a reference to whatever lexical environment we choose.

Closures are cool, right? They were there all along, you just didn’t notice them. They’re not attention seekers. They’re wallflowers. You kind of have to seek them out, before you really get a sense of who they are. But like most introverts, they are worth the time and effort it takes to get to know them.

Hopefully I’ve made a nice introduction. 😅

This article is part of a series on digestible code concepts for folks newer to web development, who are searching for better approaches to solving problems with code.

--

--

Bobby Tate
The Startup

Software Developer doing life in Nashville, Tennessee. I like to write articles about JavaScript, and I try to make them somewhat beginner friendly.