Closures are confusing because they are an “invisible” concept.

When you use an object, a variable, or a function, you do this intentionally. You think: “I’m gonna need a variable here,” and add it to your code.

Closures are different. By the time most people approach closures, they have already used them unknowingly many times — and it is likely that this is true for yourself, too. So learning closures is less about understanding a new concept and more about recognizing something you have already been doing for a while.

tl;dr

You have a closure when a function accesses variables defined outside of it.


You can stop reading here, if you want. The rest of this article approaches closures in a different way. Instead of explaining what a closure is, it will walk you through the process of discovering closures — like the first programmers did in the 1960s.

Step 2: Wrapping Code in a Function Call

Using a function gives us the ultimate flexibility because we can run this function any number of times, at any time — and from anywhere in our program.

In other words, if we take some piece of code, “wrap” that code in a function, and then call that function exactly once, we haven’t changed what that code is doing. There are some exceptions to this rule which we will ignore, but generally saying this should make sense. Sit on this idea until your brain feels comfortable with it.


Step 3: Discovering Closures

We have traced our way through two different ideas:

There are languages in which a code structured this way is not valid. For example, this code is not valid in the C language (which doesn’t have closures). This means that in C, our second conclusion isn’t true — we can’t just take some arbitrary piece of code and wrap it in a function. But JavaScript doesn’t suffer from that limitation.

Let’s go through this code together — step by step. First, we declare the liveADay function at the top level. We immediately call it. It has a food local variable. It also contains an eat function. Then it calls that eat function. Because eat is inside of liveADay, it “sees” all of its variables. This is why it can read the food variable.

This is called a closure.

We say that there is a closure when a function (such as eat) reads or writes a variable (such as food) that is declared outside of it (such as in liveADay).

A Ghost of a Function Call

Closures might seem deceptively simple now. This doesn’t mean they’re without their own pitfalls. The fact that a function may read and write variables outside has rather deep consequences if you really think about it. For example, this means that these variables will “survive” for as long as the nested function may be called:

Why “Closures”?

Finally, you might be wondering why closures are called that way. The reason is mostly historical. A person familiar with the computer science jargon might say that an expression like user => user.startsWith(query) has an “open binding”. In other words, it is clear from it what the user is (a parameter), but it is not clear what query is in isolation. When we say “actually, query refers to the variable declared outside”, we are “closing” that open binding. In other words, we get a closure.

Not all languages implement closures. For example, in some languages like C, it is not allowed to nest functions at all. As a result, a function may only access its own local variables or global variables, but there is never a situation in which it can access a parent function’s local variables. Naturally, that limitation is painful.

There are also languages like Rust which implement closures, but have a separate syntax for closures and regular functions. So if you want to read a variable from outside a function, you would have to opt into that in Rust. This is because under the hood, closures may require the engine to keep the outer variables (called “the environment”) around even after the function call. This overhead is acceptable in JavaScript, but it can be a performance concern for the very low-level languages.

And with that, I hope you can get a closure on the concept of closures!

If you prefer a more visual approach to the JavaScript fundamentals, check out Just JavaScript. It is my illustrated course in collaboration with Maggie Appleton.