Kyle Simpson: Let's do a quiz. What is a closure and how is it created? In other words, I want you to give me back my definition. What is a closure and how is it created?
Speaker 2: A closure is a function that can be called, that keeps its lexical scope when it's called somewhere else.
Kyle Simpson: Exactly, a closure is when a function remembers and accesses its lexical scope even when that function is executed outside of its lexical scope. How is it created? When an inner function is transported outside of the outer function. How long does its scope stay around?
Speaker 2: There's no longer any references.
Kyle Simpson: Yeah, so, what we basically said was, a closure is kind of like a reference to a hidden scope object. So, as long as there's some function that still has a closure over the scope, that scope's going to stay around. But as soon as that closure goes away, scope can get garbage collected.
Kyle Simpson: Why doesn't a function callback inside of a loop behave as expected? What was wrong with that little for loop with the set timeout inside of it?
Speaker 3: It wasn't actually creating it's own variable.
Kyle Simpson: Yeah there wasn't a variable created per iteration. We thought that somehow, magically, it was but it wasn't.
How did we solve that? What was the canonical way to solve it?
Speaker 3: Ify.
Kyle Simpson: Putting an ify inside of the iteration, that did it. Also, the other solution?
Speaker 3: The let-
Kyle Simpson: The let keyword. Putting a let keyword on the for head or inside the for loop, that also creates scoping.
How do you use a closure to create an encapsulated module? There were two characteristics. What were they?
Speaker 4: It has to be wrapped by a function.
Kyle Simpson: It has to be an an outer wrapping function. That's the first one. The second one?
Speaker 4: Return the inner functions.
Kyle Simpson: Return one or more inner functions that have a closure of the scope.
What are the benefits of that module pattern? Why is that beneficial?
Speaker 3: Create private in public.
Kyle Simpson: Hiding stuff, the principle of least exposure, hiding things, having a public API. It's the idea of not exposing inner details that you don't want people to accidentally rely on undocumented features, all of those benefits.
Anybody think of a trade-off to the module pattern?
Speaker 3: A couple of trade offs.
Kyle Simpson: One trade off that some people, it's not a trade off in my opinion because I have a different opinion about what testing means. But some people don't like the module pattern because it hides a bunch of stuff and it makes that inner stuff hard or impossible to test.
One of the benefits of having everything public is that everything's testable, right? So we have this idea of unit testing, and theoretically, unit testing says we should unit test every single function. I disagree with that definition of unit testing, to be personally honest. I think a unit is the smallest indivisible unit of code.
So if a module has a hundred inner functions and only one public API, there's just one unit test, and it's for that one public API. That's my own take on testing. But some people think it's a downside that you have all that hidden stuff and you can't individually test any of the implementation details.
So that's one trade off, anybody think of a different trade off?
Kyle Simpson: Might have been a little bit subtle so I'll help you. Every time I create a new module. Remember, I have this function that can churn out a new module, am I creating a whole copy of all that internal functions?
So let's say I had one little module factory and I wanted to create 1,000 instances of my module, I'd have 1,000 copies of all of its functionality. So I'm creating a whole bunch of extra copies. We will see in the next section of our discussion, we'll see a way that that particular drawback can be addressed.