Photo by Masaaki Komori on Unsplash

3 Use Cases for Closures (in JavaScript)

Ilya Meerovich
May 3, 2020 · 5 min read

Closures can seem like a daunting topic to anyone who’s relatively new to programming. They represent a topic that lies beyond the core programming concepts that are part of most introductions to the field — primitive data types, variables, functions, basic control flow, etc.

Nevertheless, closures are a very straightforward concept, so I want to explain them as I understand them, and provide some examples to illustrate why you might want to use them. In this way, they can go from being an abstract concept to a technique you can actually deploy in your everyday code.

What is a closure?

Let’s examine why that’s not intuitive.

In the code below, everything works exactly as we expect:

Now consider the following:

We have two functions, outer and nested. When the first function is called, it returns the second one. In the code above, by the time we call nestedFunc (which is a reference to the nested function), the outer function has already returned. We don’t expect that nestedFunc can access the variable two when it is called, since that variable is not in scope when we call it.

And yet, it does. This is a closure — a function that has access to all of the variables that were in scope when it was declared.

This is an interesting feature that is available not just in JavaScript but in many other languages. Let’s now take a look at where it might come in handy. The following examples are contrived, but may be helpful in showing the kinds of things we can achieve with closures.

1. Tracking DOM State / Styles

Suppose you had the following markup:

and you wanted to be able to programmatically change the div’s styles, while keeping track of its initial styles in the event that you wanted to revert back to them. Closures can help us out:

The above code is a function that returns two things when passed a valid DOM selector — a getter for the initial value of any style prop on the element, and a setter to modify any value.

Note that we need to assign window.getComputedStyle to a new object, otherwise every time we try to access properties on initialState, the values will get recomputed and the initial styles are lost.

We could consume it as follows:

We can create as many of these as necessary for whatever DOM elements we’re interested in tracking or updating.

2. Singletons

In the example below, we use the singleton pattern to construct a really naive logging service:

The above code makes use of the IIFE or Immediately Invoked Function Expression to return the object with the info, warning, and error methods on it. That’s why we didn’t have to call the service like a function, i.e. LoggingService() — it’s not a function, but rather the return value of the function.

As we can see if we run this, the three methods on the LoggingService object have access to the string variables in the closure. We could augment this service by adding whatever variables we want, they will all be available to the log methods.

This might not be the best approach for large applications where we might have multiple processes running, each with their own logger, as there is no way to configure the options for this logger from outside. In that scenario, we’re probably better off creating a logger class that we can instantiate with different configuration options.

3. Higher-Order Functions

One simple example is a function that creates functions to help us round integers to a certain number of decimal places. Imagine in some cases we have a float that we want to round to the nearest whole number, while in some cases we want to maintain two decimal places.

Here is the (somewhat) long version:

We can use closures to create a utility function that makes this a little bit easier to work with:

The way we use closures in this example is by ‘closing over’ the argument to rounder. After rounder has returned, we wouldn’t expect the inner function to have access to the places parameter, yet that variable is preserved in the closure.

Following this example, we can create an arbitrary amount of ‘rounders’ for all our rounding needs…or generate-a-random-number-in-a-range needs, or string formatting needs, and so on. You get the idea.

A note on private methods

Other languages like Java, for instance, have support for private methods, as well as other access modifiers that determine how certain methods or variables can be accessed. Traditionally, JavaScript did not have support for private methods, so closures were used to implement it instead.

As of this writing there is a Stage 3 proposal from TC39 to add support for private methods to JavaScript, so we won’t really need closures for this anymore.

The new syntax for declaring private methods is to prepend a # to the variable name, as follows:

That being said, here is how we would’ve accomplished this with closures:

Closures are everywhere in JavaScript as well as in other languages (not necessarily functional ones), and are a cornerstone of functional programming.

As you might expect, MDN has a fantastic page on closures, and the Wikipedia article goes into great detail about still other applications of closures, as well as how they work in other languages.

I hope the notes above alleviate some of the confusion around the topic of closures, and inspire you to investigate more functional programming techniques!

Resources

Wikipedia article on closures: https://medium.com/r/?url=https%3A%2F%2Fen.wikipedia.org%2Fwiki%2FClosure_%28computer_programming%29

TC39 Class fields proposal: https://medium.com/r/?url=https%3A%2F%2Fgithub.com%2Ftc39%2Fproposal-class-fields

Misko Hevery’s article on Singletons: https://medium.com/r/?url=http%3A%2F%2Fmisko.hevery.com%2F2008%2F08%2F17%2Fsingletons-are-pathological-liars%2F

The Startup

Get smarter at building your thing. Join The Startup’s +787K followers.

Sign up for Top 10 Stories

By The Startup

Get smarter at building your thing. Subscribe to receive The Startup's top 10 most read stories — delivered straight into your inbox, once a week. Take a look.

By signing up, you will create a Medium account if you don’t already have one. Review our Privacy Policy for more information about our privacy practices.

Check your inbox
Medium sent you an email at to complete your subscription.

Ilya Meerovich

Written by

A dev from Vancouver. • https://ilyameerovich.com

The Startup

Get smarter at building your thing. Follow to join The Startup’s +8 million monthly readers & +787K followers.

Ilya Meerovich

Written by

A dev from Vancouver. • https://ilyameerovich.com

The Startup

Get smarter at building your thing. Follow to join The Startup’s +8 million monthly readers & +787K followers.

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

Get the Medium app

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