Check out a free preview of the full The Good Parts of JavaScript and the Web course
The "Closure" Lesson is part of the full, The Good Parts of JavaScript and the Web course featured in this preview video. Here's what you'd learn in this lesson:
Doug believes closure is one of the best features of JavaScript. Closure is when the context of an inner function includes the scope of the outer function. The inner function retains this context even after the outer function has returned.
Transcript from the "Closure" Lesson
[00:00:00]
>> [MUSIC]
[00:00:03]
>> Douglas Crockford: I promised you some good parts. We're finally getting to a good part and this is something that you probably don't have experience with. It's something called closure. It's also called Lexical Scoping or Static Scoping. It's a consequence of functions that can nest and functions that are first class values, and JavaScript has it, and is almost completely right in the way it implements them, and it's maybe the best feature ever put into a programming language.
[00:00:32]
The context of an inner function includes the scope of the outer function and the inner function enjoys that context even after the outer function has returned. I expect that statement made no sense to you at all and I understand that. So, I'm gonna have to explain this in steps.
[00:00:52]
So, we'll start with the observation that functions scope works like block scope. So, you're familiar with the idea of block scope. So next year, we'll probably have let statements in most of our systems. And here, we've got two blocks. One inside of the other and the inner block can see its variables, and the variables of the outer block.
[00:01:15]
The outer block can only see its own variables. So, I assume everybody is comfortable with the idea of block scope. We've had that since 1960 and it's great. So, we can do the same thing with functions. You can think of a function as simply being a block with a little bit of extra mechanism attached to it, so that you can invoke it in the future.
[00:01:35]
That you don't have to do it immediately and the same relationships apply. So we've got the yellow function, which can see a and b and the green function that can only see a. Exactly the same relationship and we can represent this relationship as sets. So, this is the set of variables that the outer function can see and this is the set of variables that the inner function can see.
[00:02:04]
Nothing surprising here, except that we can describe this relationship in that the set of variables of the inner function encloses the set of the outer function and that's why we call this closure.
>> Douglas Crockford: And it's kinda too bad that we call it closure, cuz most people think of closure as meaning something else, like retribution or vengeance.
[00:02:28]
Have been victimized, but I'm getting me some closure and it's gonna feel good. But it's not that kind of closure, but that's what we're calling it. So, we're kind of stuck with that and it seems like a simple idea. Just add nested functions, which have what should be an obvious relationship, because of the way that scope works, but it took a long, long time for this idea to get developed.
[00:02:53]
So, you needed a language that had three things. He needed lexical scoping. He needed nested functions and functions, as first class values. And pretty early on, we got functions that would have two out of three, but we didn't get a function that had all three until scheme. Scheme was an experiment at MIT in an attempt to understand Carl Hewitt's after model in their early 70s.
[00:03:19]
The experiment failed in that they never did understand what Carl was talking about, but they did discover this new way of programming, which I think was the most important breakthrough in the history of computing. And like all of the really important, significant breakthroughs, the world took no notice of it whatsoever.
[00:03:39]
And in fact, it took two generations before we finally figured out that this was a good idea and brought it to the mainstream, but it was always a good idea and the reason it took so long was because of this problem. So, we've got the same thing we had before where we got an inner function and an outer function.
[00:04:00]
But this time, the inner function survives the execution of the outer function, because the outer function is returning the inner function. So we will call the green function, it'll allocate a on the stack. It will return a new function and exit. Now we want to call the yellow function that it returned, but yellow function wants access to a, but a is no longer on the stack.
[00:04:28]
Boom. It took us 20 years, 40 years to figure out what to do about this. Turns out the solution is trivial. Don't use a stock, allocate all of the activation records on the heap. Get a good garbage collector, done. Really, really easy, but it took a long time to figure this out.
[00:04:48]
>> Speaker 2: Can you repeat that solution?
>> Douglas Crockford: Yeah, don't allocate the activation records on the stack. Allocate them on the heap. Get a good garbage collector, done.
>> Douglas Crockford: That's it. That is the whole whole thing. So anyway, this idea is discovered in scheme. Takes a long time for to finally get to the mainstream.
[00:05:15]
Anybody happen to know what was the first language to bring this idea to the mainstream was? Anybody? This JavaScript. Javascript was the first language to do this followed quickly by Python and Ruby, C# got it. Eventually, C++ got it. PHP does it in a really half-assed way, but they got it just last year.
[00:05:40]
Java finally got it. Java was having a tough time keeping up with his stupid little brother, but it finally got this. This idea took so long to get to the mainstream that there was an opinion that, well, it's not getting to the mainstream, cuz it's not a good idea.
[00:05:56]
The proof that it's not a good idea is that it hasn't been adopted, but we're now adopting it and we're adopting it, because it turns out it's the solution to a lot of the problems that we're having now. Dealing with distributed systems and asynchronicity, and the things that we do now much easier if you've got functions working for you.
[00:06:17]
And this particular pattern where we have a function that survives another function, a function that returns a function is an incredibly powerful important construction. It's amazingly useful. Amazingly powerful and we got it and we got it first with JavaScript, which is amazing.
Learn Straight from the Experts Who Shape the Modern Web
- In-depth Courses
- Industry Leading Experts
- Learning Paths
- Live Interactive Workshops