Check out a free preview of the full Deep JavaScript Foundations, v3 course:
The "Closing Over Variables" Lesson is part of the full, Deep JavaScript Foundations, v3 course featured in this preview video. Here's what you'd learn in this lesson:

Kyle distinguishes between what it means to close over a variable instead of a value through code examples.

Get Unlimited Access Now

Transcript from the "Closing Over Variables" Lesson

>> Kyle Simpson: Here's an example that tries to point out that it's not a snapshot. And this is one of the perpetual frustrations that developers seem to have. They get this idea, okay closure, but then they immediately jump to the assumption that that means that I'm snapshoting a value. That I'm capturing some value at some moment.

[00:00:20] That is not what closure is. Closure has not got anything to do with the values at all, as a matter of fact. You don't close over a value. I've seen that countless times in blogs and books. There is no such thing, that is nonsense, there's no such thing as closing over a value.

[00:00:37] You close over a variable, which means you have a linkage to that variable. Which means at the time you access it, you're seeing whatever value that variable has at that moment, not it had before. Here in this example when I create the myTeacher function on line 3, at that moment teacher has the value Kyle.

[00:00:56] And then later I change teacher to the value Suzy. And then line 9 when I execute the function what's it gonna print? Not Kyle, we didn't close over the value Kyle, we closed over the variable teacher. And when we execute that function, we're gonna access the value of it.

[00:01:15] It is a live link to all the variables that you are closed over. So don't think of closure as capturing values, think of it as preserving access to variables.
>> Kyle Simpson: The place where this bites people the most, the most classic canonical example, is whenever you try to create closures inside of a for loop, or inside of any kind of looping mechanism.

[00:01:38] Not usually with timers, but that's just a convenient illustration here. Normally it's like assigning click handlers to an array of buttons for example. And this function, that is being created in each iteration, it has the appearance that what it's doing is closing over the i value in each iteration.

[00:01:56] So we're expecting it to print out i 1, i 2, i 3, but when we run it it prints out 4, 4, 4. Why? Cuz there's only one i variable. There's an i variable on line 1 and there's only one of them, and we have three functions. If we wanted to have three separate values, how many variables would we need?

[00:02:21] This is not hard math. If we wanted three separate values, how many variables do we need? We need three variables, right? And there's only one, so of course it can only have the one value. And in this case, it's gonna have the value that occurs at the end of the loop, which is the value 4.

[00:02:40] We can't effectively use closure until we separate ourselves from that perception of capturing values. It's not capturing a value, preserving access to a variable, okay? So, if we wanted to solve this problem, and we analyzed that, I need separate variables, we've seen several multiple different examples of how to create variables.

[00:03:06] If we wanna create more than one variable with the same name, we need to make new scopes, right? So we could do an iffy here, but the much more common way now that we have ES six, now that we have blockscoping, is to just stick a block scoped declaration in the iteration.

[00:03:22] So now let j is going to run every time the 4 loop iterates. And it's gonna create a whole new j in that whole new iteration of the loop. When we close over it on line 4, we are closing over a whole new j. There are three separate js and therefore we get the values in them 1, 2, and 3.

[00:03:43] See the difference between capturing a value and closing over a variable? It turns out there's an even, I think better some people might say trickier, but there's an even better way of solving this problem. Because that perpetual problem of I'm doing for var i and my closures aren't capturing the value.

[00:04:03] That's been a problem for JavaScript developers for like 20 years. They decided with iOS six, well, why don't we just go ahead and make it so that if you use a let on your for loop we'll automatically create a new i for each iteration. Instead of creating just one that belongs to the whole for loop here there's gonna be a brand new i for each iteration.

[00:04:26] Which means the closure just magically works, okay? The point is if you need multiple different values being closed over you need multiple different variables. You need to close over different variables, not try to capture values.
>> Kyle Simpson: Yes?
>> Speaker 2: So, the i is defined actually inside, even though it's written this way, but is it actually then defined inside the block?

[00:04:55] Is that basically what it is?
>> Kyle Simpson: Yes, it is interpreted as if each iteration there's a new declaration of i, and JavaScript takes care of assigning it the value that it had that its cousin had at the end of the previous iteration. It wires up all that stuff for you.

>> Speaker 3: Is there any other case were that applies as well or is that the only one?
>> Kyle Simpson: All of the for loop forms have a for let variance. So for here, we have for let of. We have let,
>> Speaker 4: Each?
>> Kyle Simpson: Well, for each isn't a syntactic form.

[00:05:30] That's a iterator, so you already get a function with that one.
>> Kyle Simpson: [COUGH] But yeah, for, for of, and for in, those three syntactic for loops automatically make their thing inside of the iteration.
>> Kyle Simpson: By the way, just as a little tiny detail, not that many people are gonna run across this.

[00:05:54] But if you did try to use a const there, you're gonna get an error because that i++ is trying to modify the variable. So here you would need to use a let. So closure is a preservation of the linkage to a variable, not the capturing of the value.