Part 1: What is a Closure in JavaScript?

Bret Doucette
4 min readJan 4, 2017

--

This is Part 1 of my I Need To Learn More JavaScript series.

What is a Closure?

A closure is an inner function that has access to the outer function’s variables and parameters.

Below the function called inner is considered a closure. That’s it.

Closure Example

Why is this Important?

In the example above, a closure is simply a function inside of another function.

The inner function, named inner, has access via lexical scoping to variables in outer function’s scope, which in our case are the two variables innerNumber and outerNumber.

In other words, a closure means that an inner function always has access to the variables and parameters of its outer function, even after the outer function has returned.

Understanding Variable Access

Let’s look at this example below:

The closure here is combineNames. It has access the outer function’s variables and parameters, intro & firstNames respectively.

When I execute the outer function like this: const mickeyMouseFullName = fullName('Mickey'), the outer function fullName is called and returned.

Remember I said above that the inner function still has access to the outer function variables and parameters even after the function has been returned.

In other words, the function combineNames still as access to the outer function variables and parameters, despite the fact that fullName, the outer function, has been called and returned once.

Also on line 7 in the gist above, we return the combineName function as the return value of the fullName function.

Because we explicitly return combineNames (the closure function) as the return value of outer function, fullName, our variable definition, mickeyMouseFullName, now contains a reference to the closure function combineNames (see image below)

The variable mickeyMouseFullName now contains a reference to the closure function, combineNames.

RECAP: At this point the variable mickeyMouseFullName has access or a reference to three things:

  1. It has access to the variable of the outer function intro // 'Hello' via lexical scoping
  2. It has access to the parameter of the outer function that was provided on the first execution firstName // 'Mickey
  3. It has a reference to the closure function — combineNames (see image above)

Now when we execute:

mickeyMouseFullName('Mouse')

The following will be printed to the screen:

==> Hello Mickey Mouse!

Why?

Like I said above mickeyMouseFullName contains a reference of the inner function (see image above) as well as has access to the outer functions parameters and variables, including those from the previous execution.

Having everything the inner function needs, the inner function combineNames executes its code and we see the following:

return `${intro} ${firstName} ${lastName}! ==> Hello Mickey Mouse!----------intro -- defined in the outer function available via lexical scoping 
firstName -- provided as a parameter to the first execution of outer function
lastName -- provided as a parameter to the closure function

Conclusion / TLDR

When you have a closure, the inner function, the closure, still has access to the outer function’s scope. It does this by storing references to the outer function’s variables. It does not store the actual value.

This allows you can call the inner function later in your program with access to the outer function’s variables or parameters from previous executions.

Some Other Fun Stuff

Why would I use closures?

Closures ensure data privacy.

The variables enclosed by the closure are only in scope within the containing (outer) function. For example…

let add = function () {
let counter = 0

return () => {
return counter += 1
}
}() *note I immediately invoke the function here
add() //prints 1
add() //prints 2
add() //prints 3

Here the variable counter in the anonymous closure (inner) function can access the counter variable in the outer function.

Even cooler, the variable counter in the anonymous closure function is protected by the scope of the anonymous function and can only be changed using the add function.

Closures provide a great way to more or less create private variables.

When Can Closures Go Wrong?

Memory leaks or memory that isn’t being used and that also isn’t being picked up by garbage collection.

Simply speaking with JavaScript, garbage collection works by keeping variables that have a reference and cleaning up those that do not.

As I stated above, closures work by storing references to the outer function’s variables. They do not store the actual value. So if you are working with rather large datasets and have lots closures that are storing references to these rather large datasets, garbage collection will not clean up these references.

This references will take up memory and overtime you could expect your app’s performance to slow down or downgrade.

--

--