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.

For example, this code snippet contains a closure:

let users = ['Alice', 'Dan', 'Jessica']; let query = 'A'; let user = users.filter(user => user.startsWith(query));

Notice how user => user.startsWith(query) is itself a function. It uses the query variable. But the query variable is defined outside of that function. That’s a closure.


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 1: Functions Can Access Outside Variables

To understand closures, we need to be somewhat familiar with variables and functions. In this example, we declare the food variable inside the eat function:

let users = ['Alice', 'Dan', 'Jessica']; let query = 'A'; let user = users.filter(user => user.startsWith(query));

Step 2: Functions Can Access Outside Variables

To understand closures, we need to be somewhat familiar with variables and functions. In this example, we declare the food variable inside the eat function:

let users = ['Alice', 'Dan', 'Jessica']; let query = 'A'; let user = users.filter(user => user.startsWith(query));

Step 3: Functions Can Access Outside Variables

To understand closures, we need to be somewhat familiar with variables and functions. In this example, we declare the food variable inside the eat function:

let users = ['Alice', 'Dan', 'Jessica']; let query = 'A'; let user = users.filter(user => user.startsWith(query));