This course has been updated! We now recommend you take the Deep JavaScript Foundations, v3 course.
Transcript from the "Closure Review" Lesson
[00:00:00]
>> Kyle Simpson: So let's review our information so far, and then we'll get to an excercise. What is a closure and how is it created? In other words, without cheating and looking back at the slides, tell me that definition for closure again.
>> Speaker 2: The ability for a function to remember its scope.
[00:00:15] It's a lexical scope.
>> Kyle Simpson: That's one part of the definition, what's the second part?
>> Speaker 3: Even outside the lexical scope.
>> Kyle Simpson: Even when the function is executed outside of that lexical scope. It's a two-part definition, if you only have one of the two parts, it's not closure. Just having a function access variables, that's just called lexical scope.
[00:00:34] Just having a function run in a different scope, but it doesn't access any variables, that's just a function. Having a function access variables when running in a different scope, that's closure, okay? How is it created, well, you declare a function inside of another scope, and you reference a variable from its outer scope.
[00:00:55] The closure's created for you.
>> Kyle Simpson: How long does the scope stay around? [COUGH]
>> Kyle Simpson: How long does a scope that's been closed over stay around?
>> Speaker 2: Until there's no references.
>> Kyle Simpson: Until there's no more closure over it, right? So if there's 1,000 closures over it, and 999 of them go away, and 1's hanging around, that scope's still hanging around.
[00:01:20] Soon as that last closure goes away, the scope is then free to be garbage-collected.
>> Kyle Simpson: What was wrong with our whole loop with the function callback inside of it, then, what was the main issue? Not the surface issue, but the main issue?
>> Speaker 2: [INAUDIBLE] was that we were, change var to let, that [CROSSTALK]
[00:01:45]
>> Kyle Simpson: Well, that was one way that we solved it. But the main issue was that we needed a different i for each iteration, but we only had one i. So we were, of course, were closing a bunch of times over the same variable. So there were multiple ways that we fixed it, one was the IIFE.
[00:02:01] Remember, we put the IIFE inside of the for loop, that created a new i. Then we did a let j inside of the for loop, and that created a new j for each iteration. Finally, we put the let directly in the for header, which created a new i for us.
[00:02:15] All three of those were valid ways of creating a new variable for each iteration, okay?
>> Kyle Simpson: Finally, what are the two characteristics that make the module pattern?
>> Speaker 2: Has to run once.
>> Kyle Simpson: There has to be an outer enclosing function that runs once, that's the first characteristic.
>> Speaker 4: An inner function that returns, I guess, return.
[00:02:40]
>> Kyle Simpson: An inner function with closure over that internal scope, that gets returned on the public API. So we didn't really talk about this, but I wanted to take a moment. What do you think are the benefits to the module pattern? In your own words, how would you describe why the module pattern might be beneficial to code?
[00:02:57]
>> Speaker 3: Organizing code in a meaningful way.
>> Kyle Simpson: Organizing code, yep, that's true, but we can also organize code with namespaces. So organizing's good, what's another benefit to the module pattern?
>> Speaker 2: Access, give access.
>> Kyle Simpson: Restricting access, right, so that we are defensive. We're not exposing something that somebody's going to use in a way that we weren't expecting.
[00:03:16] Which then prevents us from refactoring later. Primarily, the module pattern benefit is the encapsulation, the hiding of things that we don't want to expose. Now, what do you think the downsides might be of the module pattern? One downside doesn't get talked about a lot, testability. If you are of the persuasion, cuz there are different schools of thought, within testing.
[00:03:43] Within testing, you might have a black-box tester. Who's somebody who wants to test stuff from the outside, doesn't care about the internal details. But you might have somebody else who's a white-box tester, they test every internal detail that they know about. Those folks, often, in terms of unit tests, they want a function.
[00:04:04] Or they want a test for every single function in a piece of software, even if it's normally just a hidden internal private function. So they use, as their definition for the word unit, function. And every function needs to be tested, cuz there needs to be a unit test for everything.
[00:04:22] So then the question becomes, how are you gonna test a function if it's hidden?
>> Kyle Simpson: And we have had people invent all kinds of interesting-slash-crazy approaches to that, for example, dependency injection. Where you inject the testing apparatus into the internals of your module, so that it can test itself from the inside-out, or or other things like that.
[00:04:46] Some people have had code rewriting, which will take a module, and rewrite it with public codes so that they're accessible. Or other kinds of crazy things, there's lots of ways that you might approach it. So the module pattern may have an effect on your testing strategy. If you're of that persuasion, the module pattern sort of actively fights against you.
[00:05:06] And you have to invent these other, more sophisticated ways to test stuff. I happen to be of the opposite, the black-box perspective, which says a unit is not a function. A unit is the single indivisible piece of business logic, whatever that happens to be. Which might just be a giant module with thousands of internal details, and one public API method.
[00:05:30] Well, my unit test needs to test the public API method. The rest of the details are private, because they're supposed to be private. That's the way I think about testing, so for me, the module pattern fits. But if you think the other way, the module pattern might get in your way.
[00:05:45] That's one set of downsides to consider, when choosing the module pattern.