Check out a free preview of the full Functional-Light JavaScript, v3 course:
The "Closure" Lesson is part of the full, Functional-Light JavaScript, v3 course featured in this preview video. Here's what you'd learn in this lesson:

Kyle introduces closure, a function remembering its variables no matter where it is being called, as an essential concept to understand for functional programming. Kyle then discusses how to close over parameters to preserve the purity of a function.

Get Unlimited Access Now

Transcript from the "Closure" Lesson

[00:00:00]
>> Kyle Simpson: All right, so we've already hinted at the idea of closure in this course. A couple of time, we've already used it. But I wanna be very specific about a definition for closure, cuz there's a lot misconception about this concept. And it is absolutely essential. You just cannot do functional programming without a solid understanding of closure.

[00:00:21] So I wanna give you a very specific definition for closure that is based upon what we can observe in our programs. And that is closure is when a function remembers the variables around it even when that function is executed elsewhere. And by around it I mean any variables that you access outside the function that aren't directly passed in, they're accessed like for, remember when we accessed global variables, things like that.

[00:00:47] Anytime you access a variable from an outer scope, and then you take that function that is doing that access, and you pass it somewhere else, and you run it in a different scope. If you thought about it logically you'd say, well, it should forget about that variable, cuz it's running in a different scope.

[00:01:04] But it doesn't forget about the variable, and the reason it doesn't is because of closure. And if that sounds too abstract to you, let me remind you that we've already seen this several times in code we've looked at today. Here's an example, I'm illustrating the idea of closure here.

[00:01:26] I have a makeCounter function. makeCounter doesn't take any inputs in it. It declares a variable, line 2, called counter and it returns us back a function, which every time we call it, is going to increment that counter variable. So on line 8, I make my counter, I say var c = makeCounter.

[00:01:46] And I call c with no inputs, and I get back the value 1. And then I call c with no inputs and I get back the value 2, and then 3, and then 4. So it's in a counter, right? Could be useful in our programs to have a counter.

[00:02:00] But let me ask you, this is definitely closure because we have the inner function increment, closing over that counter variable. It's remembering it, even though makeCounter has finished, the C function still remembers it and can still keep updating it. That's how it works. That's called closure. But I wanna ask you, is the C function a pure function call?

[00:02:29]
>> Kyle Simpson: Look at like 10, 11, and 12. Are those pure function calls?
>> Student: It can't be because it's pulling from the dom.
>> Kyle Simpson: It's not pulling from the dom.
>> Student: Or pulling information.
>> Student2: Not getting the same output.
>> Student: Yeah.
>> Kyle Simpson: We are not getting the same output every time.

[00:02:47] We're passing in the same input, which in this case, is no input. But every time, we're getting a different output. So it absolutely violates one of the fundamental premises of a pure function. So here's the takeaway, closure is not necessarily functionally pure. But closure can absolutely be used in functional theory.

[00:03:14] So the key is if I'm closing over a variable, this counter, it can't be reassigned. And if it's getting reassigned every time that's a big no, no because now we're not closed over a constant anymore, we're just closed over some changing state, in which case we now have an impure function.

[00:03:34] You might have to do that in your programs but that's not gonna be a pure function goal. Are you with me? So let's look at some examples of using closure that is consistent with functional style, that is going to produce a pure function. Remember unary? That was one of the first utilities that we looked at, our first higher order function, It takes it an (fn), and remembers that (fn) and uses it later.

[00:04:06] How does it do that? Why did the fn variable from line 1, the parameter, not get garbage collected when unary finished?
>> Kyle Simpson: The answer is because the inner function one which got returned is holding onto that parameter, via what we call closure. It still has access to that thing.

[00:04:27] So later on whenever we call f somewhere, it still remembers the original thing that was passed into unary by way of the parameter fn. And that's not the only example we saw of closure, remember addAnother? We talked about this one, remember how it's referencing that z variable, even though that z variable was passed in and an outer scope.

[00:04:52] The addTwo function is closed over the variable z, which is why it's able to use that later on.
>> Kyle Simpson: And the key thing here is that in the both of those slides the fn on the previous slide and the z on this slide. In both of those cases we are referencing a variable outside of ourselves, which seems like it would to be a no no, but it's safe functionally because it doesn't change.

[00:05:19] It's a memory over a thing that doesn't get modified. That's what makes it still function pure.