Lesson Description

The "Return a Function" Lesson is part of the full, JavaScript: The Hard Parts, v3 course featured in this preview video. Here's what you'd learn in this lesson:

Will walks through a thread of execution example for a function that returns another function. The returned function is saved in global memory and can be called when parentheses are added to the label given to the returned function.

Preview

Transcript from the "Return a Function" Lesson

[00:00:00]
>> Will Sentance: People, this code may look fairly alright, but it actually involves and requires a lot of precision and is a real gotcha of code. I think partly because if you come from other languages, you can't do these things. But you can in JavaScript. Okay, so we're going to define a function called create function. We're not going to go inside it, we're just going to save it. You don't go inside a function till you run it, which we're going to do in the next line.

[00:00:22]
We're going to declare a constant generated funk. Assigned to it the output and running create function, which we don't yet know what is, so we're going to go into create function, execute it, create a new function called multiply by 2. Only to not use it there, but instead return out all its code and store it into a new global label generated funk. And then in the next line, we're going to call that generated funk, knowing that it's now a function definition with parens, pass in 3, and because it's really just multiplied by 2 or was born as multiplied by 2, return out 6 and store it in result.

[00:01:06]
The thing here people about this code is nobody on earth, well I don't know, maybe. Doesn't feel a bit like when I hit that calling of generated funk in the last line, that I'm somehow going to have a connection back to create function. Because in the line before I said generated funk is create, ah, no, I said generated funk in the line before is the output of a one-time run of create function. Whatever that was, is what gets stored in generated funk, and never again will generated funk have anything to do with create function or know anything about it.

[00:01:43]
Well, besides what we'll see, besides what we'll see later on. Okay, alright, here we go, people. Let's start. Let's get walking through our code. JavaScript is turned on. There it is. Our thread of execution kicks off, and we therefore, in our global execution context, immediately have a memory, a place to store stuff as we go, both data and functionality. Chris, first line of code, what is the data or functionality, in this case, functionality that we're storing?

[00:02:23]
We are storing a thing called create function that is a bunch of text. It really is, exactly, a bunch of text stored in the computer's memory. Beautiful. Let's just make sure we've got our call stack, we might as well, just so that we are aware of what we're running. We're always in global execution context, right now, that's where we are. Quite nice, right, like you've got our global execution context, stuff we store, things we do, and we're keeping track of it here.

[00:02:54]
I don't know, I'd, thank goodness programming is so. Thank goodness our runtime is in itself, the foundations are so predictable, because then how these bits join up does get more difficult. Okay, Chris, next line, what are we declaring? We're in our memory, we're going to create a place for generated funk, and we are going to, we've got to go do some work, haven't we? Yep, we're going to make a new execution context.

[00:03:21]
Yes, a new execution context, exactly, which is going to be added to the call stack, how about that? So we're calling create. I'm just making time while I write, so keep going. Calling create funk, how do we know we're calling it, there we go, there's a question. How do we know we're creating a new execution context, how do we know we're calling create function, not just referring to it, but we're saying go grab its code and make a mini program where you can save, yep, go ahead, Austin.

[00:03:48]
Parens, exactly, new execution context, keep me going, Chris. Talk over me, otherwise I'll wish it's name on the stack. Yes, thank you. Location, yep. And then start to run that code. Beautiful. I particularly struggle with writing in that angle here. Okay, so our thread goes in and we have a local memory. Local meaning just inside of this function. Which we want to do, by the way, in part because we want to be able to in the reason we have functions, in part, is not only to make them reusable, we saw that, but also so that we can label stuff just inside of that function's execution context and not have it, quote, pollute the global namespace, meaning not have.

[00:04:35]
This is not a great example, but like, not have every time you want to use the word result, it's going to override our global, we can define stuff inside functions. So it's like creating a mini program with mini local data. Modularizing our otherwise maybe million line codebase. So Chris, absolutely, in we go, and we declare what? Multiply by 2 in memory, and that stores the function definition, exactly.

[00:05:05]
Why the heck are we doing this, by the way, we'll see, don't worry. Okay, and then we hit a key line. Return, now what are we returning? Here, Chris, we are returning that block of code. That function definition, formerly known as multiply by 2. In fact, return multiply by 2 will evaluate to, will convert to grabbing just that function definition, I'll do it in pink now I think. There it is, just that function definition, and it's that which the multiply by 2 evaluates to, turns into just that function definition, and you're like, well, hold on, now it has a name, don't panic.

[00:05:52]
As it gets returned out, our evaluation of create function, ah sorry, execution of create function will evaluate to that returned out function, and it will be assigned therefore, the function formerly known as multiply by 2 will be assigned in global to what global constant, Chris? Generated to generated funk, fantastic. I'm going to put, just, you know, it was previously known as. FKA multiply by 2.

[00:06:27]
A great pop star, okay. No, for my, for my, yeah, thanks, for my edgy music fans. Okay, good. And then we pop off this. Oh, perfect, and what do we do with this execution context? Forget it. Gone, and at least as far as I know, all labels inside, all forgotten. Popped off call stack, oh, that's not good, popped off call stack. There we go. No need for the sound effects, I apologize. There it is, excellent, now.

[00:07:04]
What happens, Chris? We are going to declare what in global. Global memory gets a result, yep, and then it calls the generated funk. Oh, excellent, I like that you said it calls generated funk. Why do I know we're calling it? Parentheses, we're going to pass what values? 3. Okay. Calls generated funk. Now, when we see this line, as humans, where do we need to go look to work out what generated funk's code is, Chris?

[00:07:41]
Where do we look, like where do we kind of visually have to go and look? Where generated funk is assigned, the previous. Agreed. And therefore, okay, what is generated funk born as? It's found in multiply by 2. It's defined as originally it's a multiply by 2 function. So when we look at this code and we see later on, 100 lines down our code, generated funk reference, we're going to walk back up the code and go generated funk was, and maybe we get this, the output of created function, and we jump up to created function, everything in us.

[00:08:18]
Forces us to feel a connection between generated funk and create function and all the insides of it, but it is absolutely not. The line, generated funk is the output of running create function, created an execution context for running create function, a new local memory in which we define multiply by 2, we then grabbed that function's code, returned it out into generated funk, and literally in memory will be stored the code.

[00:08:49]
Num, num by 2. So when JavaScript looks at generated funk, it completely forgot and create function ran. Doesn't give a damn, all it's doing is seeing that function definition, num, num by 2. But we have to go and look back up the page. That is the most distorting behavior though, because it gives us the impression that in some way generated funk is connected to create function, all of which, if we understand is not the case, will help us understand closure under the hood.

[00:09:21]
So I want to get this really precise. So we're calling generated funk, we're going to create what, Chris? An execution context, a new execution context. And what is our parameter? So generated funk is really, is the output of running create function, which was the code of what function? Multiply by 2, multiply by 2's parameter is what? Num, num, and therefore what are we assigning to it? 3, and we do 3 by 2, return it out into what global label, Chris?

[00:09:53]
Result. Result, which is 6. But Chris, where did you go and look for what the parameter name was and the, where did you go look? Back up and create function. And do we have any interest in create function at this moment? Absolutely not. It is extremely distorting to us to think we're going back up there, because JavaScript is not. It ran create function one time. Did whatever the work was, popped it off the call stack.

[00:10:25]
After returning out the code of the definition and multiply by 2, the full function, just with no name. Passing that out and assigning to generated funk, so generated funk, Joe is what? You saved multiply by 2's function definition. Perfect. Did I use it? No. What did I do with it instead? You returned the function definition and multiply by 2 to global context under generated funk. Let's give him a hand.

[00:10:51]
Excellent. If I now want to run the function, Joe, if I now want to run the function formerly known as multiply by 2 in global, by the way, why the heck would I put this in a different function first, only to return it out, but we'll come to that. If I want to, if I want to run the function formerly known as multiply by 2 in global, what name can I use now, Joe. Generated funk. Generated funk. How do I say go run it?

[00:11:23]
What symbols do I need to put on the end of it? Parentheses, spot on right. And what behavior will it, well, what is it, it's the function formerly known as multiply by 2. Does generated funk, when it runs, go and look and create function? Absolutely not, exactly, Michael, because what did we do in the line before? We ran create function, returned out the definition of multiply by 2, and saved it in generated funk.

[00:11:49]
So what, Joe, is stored in generated funk? The signature of the original function, formerly known as multiply by 2. Beautiful. So when I run generated funk, does it go look in create function for anything? No, because that line before was a one-time run, do this work, not a kind of like, if you ever see generated funk again, go run create function. Can you see how it almost looks like that, right?

[00:12:16]
You can easily think that you're saying, generated funk is always going to be go run create function, uh uh, it's in this line, run create function, whatever comes out of it, switch it the create function turns out and replace it with whatever came out of running create function. Which was the function definition, as Joe put it so well, formerly known as multiply by 2. So generated funk is and only is the function definition formerly known as, everyone together?

[00:00:00]
Multi, yeah, exactly. So when I run generated funk, what am I really running? Everyone together? 2. And when I run it, do I need to go back and to create function to get it? Everyone together? No, okay.

Learn Straight from the Experts Who Shape the Modern Web

  • 250+
    In-depth Courses
  • Industry Leading Experts
  • 24
    Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now