Check out a free preview of the full The Hard Parts of Functional JavaScript course
The "Closure Under the Hood" Lesson is part of the full, The Hard Parts of Functional JavaScript course featured in this preview video. Here's what you'd learn in this lesson:
Will covers in this section what happens within an execution context and memory when closure is used in functional programming.
Transcript from the "Closure Under the Hood" Lesson
[00:00:00]
>> Will Sentance: But let's go through this line by line and understand it incompletion. Alex, line one, what are we saving?
>> Alex: We're declaring a function, label functionCreator.
>> Will Sentance: Excellent, there it is, no different than normal. Saving it into global memory functionCreator, it's a whole function. People, we're almost there.
[00:00:21]
[LAUGH] So that's not. All right, next line, Anna, left-hand side of next line.
>> Anna: Declaring a function called generatedFunc.
>> Will Sentance: I wouldn't say that. Declaring a label generatedFunc, into which will be stored, what Anna?
>> Anna: The result of functionCreator.
>> Will Sentance: Is she right? She's spot on. Exactly the output, the executed, nothing, right?
[00:00:55]
The return value of executing functionCreator running it. And Anna, what told you that? What symbols told you that right-hand side was work to be done?
>> Anna: The parentheses.
>> Will Sentance: The parentheses, exactly. It's 1,000 times people have found this single line one of the hardest is the biggest gotcha in JavaScript.
[00:01:17]
It's not really a gotcha, gotcha is like if I were to trick. More like just we really need to understand what we're doing when we run functions. What we're doing when we say functions, we're doing when we declare labels to know what's happening this line. Okay, there it is generatedFunk.
[00:01:29]
For now it's uninitialized, I was gonna tell you why? Why we say uninitialized? Undefined was what would happen when you declared your label that was gonna be the output of the function on the right hand side with var. Then it would default one find while the function ran, and then you would redefine it as a result of the function call.
[00:01:52]
With a constant coloration, you can't have two data types changed out you can't declare it as undefined initially. Default is gonna find and then when you get the result of the function call, suddenly switch it out to whatever the result the function call is. So instead, you don't even actually fully declare the label generatedFunk until you've actually got the result of the right-hand side running.
[00:02:15]
This relates back sorry, everybody. This relates back to Charles his question much earlier about undefined versus an initialized. GeneratedFunc declared, what do we need, Anna to go and execute to figure out what to store in generatedFunk? What do we need to go and execute to figure out what to store into generated function?
[00:02:33]
>> Anna: FunctionCreator.
>> Will Sentance: FunctionCreator, let's get executing. All right, so we're gonna execute functionCreator. Anna, we need a new what?
>> Anna: Execution context.
>> Will Sentance: Excellent.
>> Anna: [LAUGH]
>> Will Sentance: And we know that whatever comes out of it is going to be stored into generatedFunc. Let's create our execution context, there it is.
[00:03:05]
>> Will Sentance: And, [LAUGH] it's a rhombus at this point. And Charles into it we go, line one. What are we gonna do? We're not gonna use this thing. I just want you to show, I just wanna make sure everyone knows we're saving stuff into memory. What's the first thing we save into memory?
[00:03:21]
>> Charles: Counter 0.
>> Will Sentance: Counter 0, exactly. Okay, I'm gonna do my cool stack as well actually for this one. It turns out to be increasingly important to think in terms of it to not get confused. All right, and first thing on it will always global, but what are we adding to it, Michael?
[00:03:43]
>> Michael: Add three, or functionCreator.
>> Will Sentance: FunctionCreator, because we're calling what function right now, Michael?
>> Michael: We're calling functionCreator.
>> Will Sentance: FunctionCreator, it gets added to the call stack. Because our execution context in action right now is functionCreators. Our thread of execution has woven into functionCreator. That's where we are right now, is top of our call stack, okay?
[00:04:10]
David, we say counter is 0 inside of local memory. David, next line, what's it say to do?
>> David: We're declaring a function with the label add3.
>> Will Sentance: Add3, there it is. Okay, are we gonna use it, David?
>> David: Not right now.
>> Will Sentance: Now, what are we gonna do with it instead?
[00:04:31]
>> David: We're gonna return it.
>> Will Sentance: Exactly, I'm gonna write that here, return add3. Anyone wanna tell me, therefore, what JavaScript actually does in that return statement? Jasmine, you wanna tell me what JavaScript does in that return statement, return add3?
>> Jasmine: Replaces add3 with a function?
>> Will Sentance: You hear this?
[00:04:49]
Exactly, it looks up the function definition using that label, and it grabs the function definition which is the bit in the parentheses, num, and then the body of that. It grabs all that and it returns it out of the call to functionCreator and stores it, Jasmine, where?
>> Jasmine: In generated function.
[00:05:09]
>> Will Sentance: Into generatedFunc she is spot on. Into generatedFunc it goes. It was formerly known as its birth name was add3, but now we returned out all the code grabbed it all, shorted out the bottom no name. We lost that name, we just returned that, we just use it to look up the function as Jasmine said.
[00:05:34]
And it got stored into generatedFunc. If I were to now console log generatedFunc, I would see input num, body, whatever it says, const result = num + 3 would return result. That is now generatedFunc. That is what it means to return a function from another function. Let's now, this is now popped off the call stack and all this goodies here.
[00:06:01]
Well, in theory, the execution context is gone. The execution code is all deleted. And [INAUDIBLE] that's really nice, and we go back out to global where we hit, what line? Sam, left hand side.
>> Sam: Result.
>> Will Sentance: Result, and the right-hand side says go run what function, Sam?
>> Sam: GeneratedFunk.
[00:06:31]
>> Will Sentance: Go run generatedFunk, and what was generatedFunks original name, Sam?
>> Sam: FunctionCreator.
>> Will Sentance: It's so easy to think it, right? What is generatedFunc?
>> Sam: Add3.
>> Will Sentance: Folk with literally 10, 15 years experience, an enormous gift in engineering still get caught by this every single time. And yet if we don't get it absolutely precise in our head, everything falls apart in understanding what's the composure.
[00:07:05]
1,000 times, I've really stressed for you, Sam is in the company of I'm literally talking about the rock stone of us at city term. [LAUGH] The superstar developer she's a person that you every single time this throws people. We've got to go run that function one time, store something in generatedFunc.
[00:07:27]
It is the functionality of add3, and from that line on generatedFunc is the code formally known as add3. Thank you, Sam honestly because everybody, who's going, yeah, I thought the same thing. Appreciate that for Sam. So generatedFunc Jasmine is the function that was born as?
>> Jasmine: Add3.
>> Will Sentance: As add3, the function definition for me known as add3.
[00:07:53]
Now known as generatedFunc, it's global label. That was it's label inside of the function created when it was originally saved just like we saved counter inside of that. But we grabbed its code, we only used, when it says return out of 3, we only used that label to find the code of the function.
[00:08:08]
Return the out stored in generatedFunc. Some of you may thinking, yeah, yeah, yeah, I got this. I promise you, people it is a real touchy. Out it comes generatedFunc is really, David, the code formally known as?
>> David: add3.
>> Will Sentance: add3, meaning after I leave functionCreator inside of which add3 was saved, I can't reference add3 anymore, it's gone.
[00:08:31]
Unless, I saved it in a new global label. David, what was that new global label I saved add3 in?
>> David: GeneratedFunction.
>> Will Sentance: GeneratedFunc, so when I run generatedFunc, I'm really running what, Eric?
>> Eric: Add3.
>> Will Sentance: Add3, so if I want to refer to Add 3 out and global, what's his new name, Andrew?
[00:08:48]
>> Andrew: Generate-
>> Will Sentance: GeneratedFunc, is generatedFunc actually functionCreator, Andrew?
>> Andrew: No
>> Will Sentance: No, what I need to change, Andrew, in order to make generatingFunc actually does a new label for the whole function creative code? What I need to change in that line so the generatedFunc is actually just a label for all the functionCreator?
[00:09:07]
>> Andrew: I remove the parentheses.
>> Will Sentance: Remove the parentheses, spot on very nice from Andrew. All right, but it is a the output of a one time running or function green, which is good. All right, I don't know if you have by the way, I promise you. This is super tricky this bit.
[00:09:21]
So let's run generatedFunc, new execution context. There it is, it's put it on the call stack. Sorry, everybody, I do apologize. We're executing generatedFunc we are brand new, [CROSSTALK] excellent generatedFunc formally know as add3, no. Yes, add3 with the input of sorry, 2, I've done this so many times with a different function that I can't get my head out of it with the input of 2, sorry folks.
[00:09:55]
There it is, with the input 2, there we go. GeneratedFunc input of 2. Now here is the especially tricky bit, in my opinion of all this. Here is the especially tricky bit of it all, is in order for me as a developer to figure out what generatedFunc is doing.
[00:10:14]
Where do I take my eye, Alex, in order to figure out what generatedFunc is doing?
>> Alex: You look at whatever was returned from functionCreator.
>> Will Sentance: Well, that is a very sophisticated way of putting it, yes. But actually, in my eye goes back up to add3 like I have to.
[00:10:28]
And so we get this false sense that JavaScript thread goes back up into functionCreator. It definitely does not, and huge shout out to, Alex for stressing that by saying actually it goes and looks what was saved in generatedFunc, which was the definition of code about 3. In fact, this f just represents the code of add3 being saved.
[00:10:52]
Now we're in global, there ain't no going back into functionCreator, that's done, that's gone. Instead, we're going and looking in the code over in here, which was roughly num, and then return out num + 3, roughly. That's where we're going to look, yeah, go ahead, Virginia.
>> Virginia: It's just a quick question, so when you say we turn at 3.
[00:11:13]
And you're saying is it doing a literal copy of add3-
>> Will Sentance: Okay.
>> Virginia: So that, when I go and say, like I say, generateFunc 2 is equal to add3. So those two different copies in memory of that function it-
>> Will Sentance: GeneratedFunc 2 is-
>> Virginia: So I can go back and say, generateFunc 2 equals to function generator?
[00:11:31]
>> Will Sentance: FunctionCreator to being-
>> Virginia: That same one-
>> Will Sentance: No, no, it'll end up being? Do you see how important it is we get our technical communication, right? So let's go on to Virginia's question in just a second, once we've got through this. But I want you to you think, Virginia, before you ask the question.
[00:11:47]
You said, if I went back and wrote generatedFunc 2 equals functionCreator-
>> Virginia: Well, calling functionCreator.
>> Will Sentance: So important, we'll come back to the question in a second, Virginia, I promise. But just, yeah, we'll come back to that in one second, I promise you, Virginia. But for now, let's stay in generatedFunc.
[00:12:04]
We're running it, everyone together, generatedFunc is a function definition that was originally known, when it was inside the functionCreator, as?
>> Add3
>> Will Sentance: Yeah, good, exactly, and so into it we go. And who said function multiplied by 2? That was a good throwback reference that someone said that.
[00:12:26]
All right, into it we go, and we, unfortunately, although we don't have to, we can go look here. What's the parameter to which the two is going to be assigned, Michael?
>> Michael: Num.
>> Will Sentance: Num, raise your hand if you look back into functionCreative to figure that out. But of course, we all do that we don't memorize all phones coming out.
[00:12:43]
But I wish we could sort of see console generated funk in that middle in between those two lines. And that's where we should always restrict ourselves make ourselves console generatedFunc to figure out what the code is we're running down there. So that we don't think of going back into our code where we were initially saved because it ain't in there.
[00:13:02]
We don't get to thread back into that, okay? But all right, number two, let me do results, which is 2 plus 3, which is 5. And then we return the value of result in to, why did I call in both results? Dear, I thought I changed that. Return the value results, everybody in to what global constant also called?
[00:13:26]
>> Results.
>> Will Sentance: That's a bad explanation by me, I apologize. Note these are in different domains and so they're not gonna override each other. Okay.
>> Will Sentance: What was I gonna ask? That was what I was gonna say. We're gonna come to thumbs, where Virginia's gonna raise her question.
[00:13:48]
Thumbs on in a moment, we saved code, functionCreator, there it is. We then saved a label generatedFunc for whatever came from a one time running of functionCreator. There's a friends to say go run functionCreator, and do we went we created a brand new function add3. And then rather than using it, we returned out its code.
[00:14:15]
And stored it under a new label generatedFunc. And from then on forevermore generatedFunc cares nothing about functionCreator. It only cares about the add3 function that's now stored in it. So we run it, and we run generatedFunc and it's just add3. We can just do it, it feels weird.
[00:14:34]
We didn't put friends on the end, no problem. And it's running add3 and put 2 into it, and it goes nominees two result is 2 plus 3 is 5, return at results into global constant result. Okay folk, you might be thinking why the hell do we do this?
[00:14:54]
Why the hell did we save a function we could have declared globally inside another? We'll see that gives our functions the biggest superpower in JavaScript.
Learn Straight from the Experts Who Shape the Modern Web
- In-depth Courses
- Industry Leading Experts
- Learning Paths
- Live Interactive Workshops