Closure is crucial for creating modules. Modules let you define private implementation details that are invisible to the outside world. At the same time, you can create a public API to allow access to necessary functionality. Kyle shares an example of how closure is used to create a module and answers a few audience questions about how it compares to other languages.
Again, remember the pattern that we want to look for is having an outer function and an inner function. Without fully understanding the mechanics of closure, if you just look for that pattern where one function sits inside of another, you'll know that's how closure ends up getting created, having one inside of the other. If I wanted to be able to hide some details, I could have an outer function called Hello and in here, it could take a name as it's initial parameter.
And inside of here, I could have a function called speak that uses that name variable. Does everybody see how that name variable is accessible to it? 'Cause of the scoping thing, right? I can always walk up and find it in a upper level. So that function speak, if I return function speak, this is exactly like what you just saw with make adder, I'm returning a function back.
For those of you online, I'm joking obviously. If I return a function that's great but what happens if I return something slightly more useful like an object? We saw earlier that blocks, when we have a pair of curly braces that looks like a block. When a curly brace pair is used in the place where you would normally expect a value, it's not a block, it's an object. Objects have properties and values on them.
Let me just do a side note here. If I said something like o equals a curly brace pair and I put a property on it like super, oh, let's not use super. Let's use awesome, that's my property name and the value is "cool". So I have an object with one property on it and that property has the value string "cool". That means, later in my program, I can say o.awesome and it will give me that value, "cool". It's a way to put property values or function methods on an object.
Isn't there a way to call speak from outside the Hello function? Let's back up. If all I do is return speak here, the only way to call that is to call it with fn(). If I tried to say speak(), would that work or would that not work? - [Student] It's out of scope. - It's out of scope. Does everyone see that this name is only available inside, it's not available outside, by those same rules of scoping.
We can go in one direction, we can go upward, but we can't go downward in the scope. So I can't call speak here but because I'm returning it then I have access to be able to call it from the outside so I can say fn() and that's what lets me annoyingly print out Kyle. But now, if we consider, instead of just passing back a single function, if we pass back an object, like this and on that object I have a property name called speak, as we see here, that is referencing this internal one.
These names do not have to match but lets just make them match for now. If this is what I return from my function instead of getting this as a function, this is an object now. Does everybody see that? What I'm getting back is an object not a function. Now, what I can say, instead of saying, o open and close parentheses, because it's not a function, what I say is o dot the property name, speak.
And to hammer that point home, if I gave it an entirely different name like say, then that's the name I could use on the outside. In other words, I have this internal function which is only accessible inside of the Hello function and I have something on the outside that is accessible only as that external name, whatever I end up calling it. Is everybody following that or am I losing people? What if you passed in an argument to say? We could definitely set this up to accept an argument and then use it, I'm just keeping the example simple.
But we could definitely set it up that I could pass in something. If I called this lastName, we could definitely use that and that would print it out. See how that's exactly like the make adder that I was showing before? It remembers one variable from its closure and it gets another one passed in, same thing as what make adder was doing.
What we're seeing here is that returning this object from a function call is essentially creating what we, in programming terms, call a public API. The stuff that's on the inside like this function, any variables that I might declare inside of there, all that stuff is completely private. We can't get at it from the outside world. But the stuff that we put in this object and return it back, that is accessible to the outside world which is like a public API to access the internal module.
- [Student] Just some questions on what's better and why? - Why would I return an object? An object would let me have multiple methods on my API. So if I had 15 inner functions and I wanted to expose five of them, I could list all five of them here and I'd have an API that had multiple public endpoints. So returning an object lets me put multiple things here. If the speak was the only function that was necessary to expose, you could, of course, just return only the function.
- [Student] So in other words, you could have your lastName as one of the properties. You could have lastName and you could return lastName or first name or whatever you define. - If I said lastName here, what value would I assign to it? - [Student] Probably the last name that was passed in. - You could conceivably want to assign off that lastName somewhere but there's no way to access this object, the way it's currently written, to be able to do that. A more realistic scenario is to suggest that we might have a method called firstName which does nothing, it doesn't take anything, except it returns back the name that we initially passed in.
So now I have two different methods, as we say, on my public API. One of them is say, which prints things out, the other one is firstName, which doesn't print anything out but it returns back that initial value that I passed in, the value Kyle. So that's two different ways of defining these methods on my public API.
Note: This course was created on 03/29/2016 by Frontend Masters. We are pleased to host this content in our library.
- Carousels, panes, and modules
- Middle-end architecture
- Secure phrase generator
- Routing functions
- Calling the API
- Rendering on the page
- Shared data validation