This course has been updated! We now recommend you take the JavaScript: The Hard Parts, v2 course.

Check out a free preview of the full JavaScript: The Hard Parts course:
The "Introducing Closure" Lesson is part of the full, JavaScript: The Hard Parts course featured in this preview video. Here's what you'd learn in this lesson:

Will reviews closures. Closures give access to an outer function’s scope from an inner function.

Get Unlimited Access Now

Transcript from the "Introducing Closure" Lesson

[00:00:00]
>> Will: Okay closure, when our functions get called, remind me, Art, how do I call a function?
>> Speaker 2: Parenthesis.
>> Will: Parenthesis. Broken record, exactly. When our functions get called, we create a live store of data.
>> Will: Inside this function, array is no longer just array. It is actually the value 123.

[00:00:25] When I refer to array inside a copy array manipulate, array is now 123. I've created a live name space with names with associated data. Known as a local memory. Known poshly, the official term in the Java script spec is variable environment. Variable environment, VE, variable environment. Known often informally as my application state, my function level states.

[00:00:59] My live data stored in memory as my application runs, for that function execution context. Every time I call a function, I create a live store. When that function finishes executing part of the call stack, its local memory is [NOISE] deleted, gone, except the return value. When we return out that value, JavaScript holds onto that data.

[00:01:21] Everything else in here it's what's called garbage collected. This is no longer data that is being used, and therefore JavaScript is gonna automatically collect and free up the memory. This is now garbage, and so it is automatically collected and cleared away. In other languages we might have to manually deallocate memory and say, we don't need this anymore, it's free for you to use the rest of the application.

[00:01:47] In JavaScript it's automatically deallocated, automatic garbage collection when we finish running the function. It's local memory's deleted. But what if our functions could hold on, somehow, to some live data between their executions? What if the next time I ran copy array manipulate, rather than it having no memory, it starts from scratch?

[00:02:11] If I ran copy array manipulate again, it would have no memory of this prior running. This whole data here, all gone. What if there a way that somehow I could hold onto some data between my functions being invoked? So I run multiplyBy2, the first time and I pass in two, the next time I run it with four, it doesn't remember the previous time it was run.

[00:02:32] There's nothing inside there remembers. What if there are a way that my multiplyBy2 could hold onto some live data? Somehow attached, associated to the definition of the function. So if I were to define multiplyBy2 here,
>> Will: That were a function. When I invoke multiplyBy2, when I run it, I have the input of 3 and create an execution context.

[00:02:58] Its local memory starts from scratch. If I ran it again, I don't know let's say I run it again with three. It doesn't matter, it's local memory starts from scratch. What if there were a way that between all these different runnings of the function, I could somehow persist, hold on to some live data associated with these function definitions.

[00:03:20] What if there were a way of doing that? That would allow me to do some amazing things. That would let our function definitions have an associated persistent memory. That would allow us to do amazing things like maybe, actually maybe remember this function's been run once before and say from now on, sorry, you can't run me again.

[00:03:39] I've been run once before. Or maybe it will allow me to do something like if the functionality were really heavy lifting and complicated and takes two seconds to figure out, well maybe if I ran, maybe the function was like n prime. And it says, run me with a thousand and find the thousandth prime number.

[00:03:58] That's hard to find. That's a lot of steps to find. If I then run later in my application, find a thousandth prime number again, I don't want to start that all over again. What if there were some way that my function definition could hold on, a little memory, a little cache to the last time I was run with a thousand, the resulting value.

[00:04:17] This would be amazingly powerful, right? This would change everything, change everything. I think it might change a lot, I think it would change how I'd write code. [LAUGH] We'll see, this will be amazingly powerful, I think. I think it would be very profound if we could do this.

[00:04:33] Who thinks it's possible? Or who thinks we're just in, maybe it's possible, who knows? Or maybe we're just hoping around [LAUGH] possible if our code could write itself. Who knows? We're not gonna discover that today. Alright, so this is what's to come. This is the essence of what we're gonna get in this closure world.

[00:04:55] But, it all starts folks with something that is gonna feel very, very disconnected from this profundity. And also by the way to some extent, it's gonna feel like, hold on, why are we doing this at all? You're gonna really ask, I wonder, why are we doing this particular thing at all?

[00:05:11] Returning a function from a function. We're gonna do that and you're gonna think? Why are we returning a function from a function? It's gonna feel very bizarre, but this underlining principle is gonna let all of closure make sense for us. So here we go, it starts with returning, it starts with us returning a function from another function.

[00:05:38] Very well written sentence, indeed, there you go.