WTF is a Closure?

Tyler Clark
InstructorTyler Clark

Share this video with your friends

Send Tweet
Published 2 years ago
Updated 10 months ago

Closure is a buzzword you'll hear in most of your programming interviews. Some say that understanding what a closure is can affect the salary your offered tremendously. So what the heck is a closure? At its simplest definition, it's a nested function that has access to at least three levels of scopes (it's own scope, the parent scope, and the global scope). Let's write out some code of a closure in action and break down what makes it unique.

Instructor: [0:00] To understand what a closure is, let's write out some code. Here, we have a const workshop global variable at the top.

[0:06] On line 3, we're going to have a parent function that has a variable itself on line 4. On line 5, we're returning a child function that has a variable inside of it. On line 7, we're going to console.log the global, the parent variable, and the child variable. On line 11, we'll invoke our parent function. On line 13, we're going to invoke our me variable.

[0:27] With this code in front of us, let's define a closure. A closure is an inner function that has access to its lexical scopes, which includes its own scope, its parent scope, and the global scope. This child function is a closure. We see on line 7 that we have access to its own const, the parent const, and the global const.

[0:46] What makes a closure function interesting is that, as we see on line 11, even though we execute parent function, our closure function still retains access to the parent's const.

[0:56] Closures do not close over a value. They only close over variables. In other words, if the global const value changes, a child function reference to it will change as well. It doesn't memorize the connection at alter time. Closures just keep their connection to variables alive even though its surrounding function executes.

[1:16] As we'll see in line 6, closures are a way to make variables private from the outside scope. We have no way of accessing this const here from anywhere else except for inside this function, which hides implementation details which change frequently in our code while programing towards interfaces.

[1:32] You might be wondering if you use closures in your everyday work. The answer is almost to guarantee yes. A common implementation of a closure is callback functions like within the array.prototype.map function. Its callback is a closure because it's a nested function within a function that has access to its parent's scopes.

Viktor Soroka
Viktor Soroka
~ 2 years ago

I know what the closure means but still the last example [1].map((a)) => a) is not quite clear.

Its callback is a closure because it's a nested function within a function that has access to its parent's scopes.

It would be if Tyler has provided more explanation to the quoted statement with regard to the given example in my opinion.

Tyler Clark
Tyler Clarkinstructor
~ 2 years ago

It would be if Tyler has provided more explanation to the quoted statement with regard to the given example in my opinion.

Anytime a function is passed as a callback argument to another function, that callback will be executed at some point within the containing function's body. Just the same as if it were defined inside of that containing function just like the example in the lesson. Which means it is a nested function with access to any variables defined inside of it, the containing parent function, and the global scope. This is why the callback arg is a closure.

Viktor Soroka
Viktor Soroka
~ 2 years ago

Thanks for a rapid response Tyler.

Tyler Clark
Tyler Clarkinstructor
~ 2 years ago

No problem!

Daniel Bokor
Daniel Bokor
~ 2 years ago

Which means it is a nested function with access to any variables defined inside of it, the containing parent function, and the global scope. This is why the callback arg is a closure.

I do understand your point of view, but I'd argue that the callback function should not only HAVE the possibility to access to any variables containing the parent context, but actually BE accessing any variables defined in the parent context (since the variables defined in the parent context would be garbage collected, unless used by the callback function).

e.g. [1, 2, 3].map((value) => { console.log('I am a callback function not actually using any variables defined within my parent scope'); });

is NOT a closure, at least from my point of view, since it does not actually access (thus close upon) any of the variables defined within the parent context.

In your example, [1].map((a) => a) the callback function uses the a variable that was defined within its own scope, not a variable defined in the parent scope.

Am I missing anything here?

Tyler Clark
Tyler Clarkinstructor
~ 2 years ago

but actually BE accessing any variables defined in the parent context

The actual implementation of a closure is different depending on the language you are programming in. Here is what MDN says about closures in JavaScript:

A closure is the combination of a function bundled together (enclosed) with references to its surrounding state (the lexical environment). In other words, a closure gives you access to an outer function’s scope from an inner function. In JavaScript, closures are created every time a function is created, at function creation time.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures

What's interesting to me is that last line.

In JavaScript, closures are created every time a function is created, at function creation time.

Tyler Clark
Tyler Clarkinstructor
~ 2 years ago

The safe bet for sure is that the inner function should be referencing something in it's parent's scope in order to remove any doubt of being considered a closure. However, I have heard both sides of this answer, which again, also depends on the programming language.

Jon
Jon
~ a year ago

I'm not really sure what the takeaway of understanding what a closure is. It seems like we implicitly understand what a closure as very early one when learning javascript - and the idea of the function scope.

Can you clear up why this term is so important to understand?

Lauro Silva
Lauro Silva
~ a year ago

This a good question Jon. Closures can trip us up, for instance with loops, if we're not careful to recognize them and how they work. On the other hand, they are also an immensely powerful tool, enabling patterns like modules in their various forms.

My takeaway from this lesson: noticing that closure is all around us in JavaScript. That it's not a new syntax or patterns that we must learn, but instead a skill that we must develop (recognize, embrace, and leverage).

The enlightenment moment should be: oh, closures are already occurring all over my code, I can finally see them now.