JavaScript: The Hard Parts, v3

Pass a Function as an Argument

Will Sentance
Codesmith
JavaScript: The Hard Parts, v3

Lesson Description

The "Pass a Function as an Argument" 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 refactors the function to accept a second parameter representing a function that should be called with each value in the array. This allows the copyArrayAndManipulate function to be generalized and mutate the array in different ways.

Preview

Transcript from the "Pass a Function as an Argument" Lesson

[00:00:00]
>> Will Sentance: So we did love these three very repeatable functions, very reusable, not very reusable functions. Let's introduce now a copy array and we'll call it manipulate. We don't yet know what we're going to do to it, and this function, people, we're going to build out line by line. So we're going to define copy array and manipulate. We're then going to define a new function which we haven't seen, or we saw it earlier, but we haven't seen in this code, multiply by 2.

[00:00:28]
All it's going to do is take in an input and return out that input doubled. But it's got to be wrapped in a function, it can't just be 2 as a string. We're then going to run copy, array and manipulate, pass in our 123, our array, and pass in a whole function, and it's going to be the whole function definition, all of its code into the running of copy array and manipulate, where we're then going to create a new output array, empty for now.

[00:00:58]
We're then going to loop through each element of the input array 123. Take the first element, 1, throw it into instructions. Ah, which will be multiply by 2, run that new execution context, 1 by 2, return it out, and that whole instructions parentheses array, or let's call it multiply by 2 parentheses 1, is going to evaluate, turn into its output, which will be 1 by 2, 2, and that'll be pushed to our output array.

[00:01:37]
So here we go, people, let's do it, and we will, from this, see all there is to see in our relatively otherwise obscure magic behind some of the functions we use every day, map, reduce, filter, and some we use every day that historically did not behave like this, reverse being one of them, and we will also in a moment, learn about some new, only in the last two years, I think it's ES 2023, functions that finally turn some of our built-in array methods that did not follow this pattern into functions that do follow this pattern.

[00:02:21]
Things like to reversed, but we'll come to that very soon. For now, let's jump in. Here we go. We have a global execution context, a global memory, and we get defining, and my lucky person is going to be Joe. Joe, what are we doing in line one? You did so well, you're back up. What are we declaring in line one? Walk me through. Declaring a function called copy array and manipulate. Manipulate, yep.

[00:02:50]
And that'll be a little nice F box all the code. Oh, I love the way you put that. Yep, beautiful. Then we will go down to do the same thing, we'll declare another function, we'll multiply by 2. Which is an even smaller little one, yeah, it's also a little exactly, exactly. Let's also, as we've turned on JavaScript, have our call stack initialized with what on the very bottom. What are we always running, yeah, global, well done, exactly, global execution context.

[00:03:24]
That's where we're running, executing our code from the moment we start JavaScript. OK, excellent. Now, what line do we hit, Joe? Now we are pointed to the constant result. Yes, we declare result, and we are going to assign it, what, do we know what to store in it yet? No, no uninitial. It's going to be uninitialized, exactly. Used to be undefined. But now we're dealing with constants, we definitely can't change a data type from undefined to the return value.

[00:03:54]
There are other things which might be interesting about how we can mutate constant, constants, but we certainly can't change its data type from undefined to an array, or whatever we get out of calling this function. It remains uninitialized, it hasn't been assigned anything yet, and we have to go and do the work, which is what, Joe? So we're getting a new execution context. Yes, excellent, to run copy array and manipulate.

[00:04:24]
I think if you say it so fast, you should have to be the one who has to write it up. OK, to which we're passing what arguments? The first argument is an array holding the values of integers 1, 2, and 3 in positions 0, 1, and 2. And the second argument is the multiply by 2 function, so yeah, it's the whole function definition. To be honest, I should really, I don't know, what color can I use, I should really like, you know, it's not multiply by 2, is it?

[00:04:56]
Sorry, it's not the label multiply by 2, we use the label multiply by 2 to find the function code, right, the F box as you put it, and that's what's going to be passed in. What's its label before we even go any further, Joe? What's the label by which we can refer to multiply by 2 inside the execution context of copy array and manipulate? It's not going to be multiply by 2, what are we going to refer to it as?

[00:05:18]
Instructions. In fact, we're going to just literally replace its label, we're going to take this function code and inside here give it a new label, so I'm just going to kind of make that clear that the pink bit is what we're actually passing in. I kept, I'm going to put little quotes around this, I kept multiply by 2 there just for our visual, but that's, OK, and as you said, a brand new, everyone together for the energy, a brand new what?

[00:05:49]
Execution context. A brand new what? Execution. So everyone was great. I was catching someone's eye who was, no, to be fair, if you're sitting by yourself right next to me, and is it extra weird to shout execution context by your, OK. Alright, there it is, new execution context, gets added to the call stack, right? Copy. Sorry, I'm, it's just I love that I choose these long names in order to make it easier to understand what these are doing.

[00:06:27]
But of course, could you think of a more silly idea than to choose long names for functions when you have to write them out? What a ridiculous idea. OK, into copy array and manipulate we go, it's top of the call stack, the thread of execution's woven its way in, and we hit first our parameter argument combinations in our local memory. So this is, yeah, go ahead, Joe, please. So in the local we have array with the array 123, and we have instructions as the F block that was initially known as multiply by 2.

[00:07:07]
Oh, thank you, Joe, you're so good. Exactly, instructions is the code, the function code, which we can just run by using the, well, let's actually go ahead. Yeah, and then we have the const output. So this was previously known as multiply by 2, do you mind if I just put this above, just so that we remember, but we know that we can't refer to it as that. It's lost that name, it doesn't care about that name because now we'll refer to it inside of this copy array and manipulate as what?

[00:07:36]
Instructions, and that's so that we don't just get to pass and multiply by 2, but we could also pass in add 3. We could also pass in divide by 2. We can pass in whatever specific code we want to have. Well, hopefully we've written this function in such a way that that specific code will hit first this element, then this element, then this element, and respectively pass them out to what new constant that we're declaring, Joe?

[00:08:06]
Output, output, which is for now, an empty array, an empty, a big old empty array. So let's head up here, and I'm just going to make it easier for us to visualize. I'm not actually copying these, I'm just making it easier to visualize. And we have, OK. So we hit the body of the for loop. And we are going to, oh, go ahead, Joe. Yeah, so now we're inside the for loop. Our initial i value is 0. Beautiful, which means we grab the 0th element of what?

[00:08:37]
Of the array. Yes, which is position, yeah, which is zero value. I'll never, I tell you, it's a weird, it's a weird interface, exactly which is the number what? 1, 1. OK. Now, so array position 0 has turned into the number 1, has evaluated, has turned into a value. Nothing in JavaScript when it's running, stays a label, it has to be evaluated, turned into whatever it actually is in memory. Here, array position 0 is the number 1.

[00:09:12]
What else is a label here that needs to be turned into what it actually is? Instructions, which is going to turn into multiply by 2. Exactly. So we have instructions position, taking away position 0, which is 1, we know that that really is running multiply by 2 with input of 1, at least the multiply by 2 function we defined out here. So we create a brand new what, Joe? Execution context, exactly. Into it we go, and in its local memory, we have an input, beautiful, of 1.

[00:09:50]
Input, we look down to our function definition, and we see input is now going to be filled in with 1, we then do what? We return 1 times 2, which is 2. And that returns out into what? And it's pushed into what? It's pushed into the output array's first position. What did I miss out? What did I forget to do? Michael, what did I forget to do with my instructions being invoked? We saw, oh yeah, by the way, how do we know to invoke, Joe, instructions, how do we know to run it?

[00:10:21]
Because we called it within as an argument in the push function. What does the instructions have on the end of it that says go run me? Parentheses, exactly, that's really crucial. If we just referred to it, we'd just be kind of copying the function code in and we have to say go run it with input of 1. And we then added it to what, Michael? Call stack. Exactly, I'm going to put instructions because that's what we're calling it inside.

[00:10:55]
And so now that's top of our call stack, but we then exited it, our thread wove in, it's weaving back out. And so, what do we, yes, we pop it off, exactly, well done to Michael, we pop it off. And now we hit. We put our 2 into output, but it's a for loop, so we hit the body of the for loop again, this time, Michael, i's value is what? 1, 1, therefore, array position 1 is what? So 2, 2, beautiful, and so we have instructions parentheses 2.

[00:11:40]
Instructions. So this execution context is closed, instructions per 2. What is instructions being fully replaced by as we evaluate that line? Multiply by 2. Yeah, spot on, Matt, exactly, so array, as we hit that line there, Michael, array position 0, array is 123, so array position 1 is the number 2, instructions got fully replaced, just like array did with. So 123, filled in the array parameter and instructions got filled in with the code of what function we defined outside of copy array and manipulate, Michael?

[00:12:19]
Multiply by 2. He's spot on, exactly, and so we're really running multiply by 2, and we know we could also be running something else. Add 3, whatever we want, because our copy array and manipulate can take in any functionality. Into multiply by 2 we go, or instructions, we go, and we do brand new execution context, add it to the call stack, and it returns out what, Joe? 2 by 2, 4, 4, which we then put where, or we push where, sorry, put's wrong, we then push where, Joe?

[00:12:54]
Position 1 of the output. Beautiful, and we have 2, 4. Are we going to do it again? No. But yes, exactly, we are going to do it again, and we get 6. So our output array is 2, 4, and 6, and now, Austin, we've got our output array. What do we do with it in the very last line of copy array and manipulate, because we don't want it stuck inside copy array and manipulate, we want it somewhere else, so what do we do?

[00:13:33]
We're going to return it. We return, let's be really precise, we return what? Return the output array? Absolutely, or return the value of output, which is our array of what values? 2, 4, 2, 4, 6, we return the value of the output array, and our whole copy array and manipulate invocation or call or execution gets thrown away and replaced with 2, 4, 6, which gets assigned to what global constant, Austin?

[00:14:06]
Result, result. There it is. Well done, everybody. We managed to run or create a function, copy array and manipulate that did not predefine what we did to each element. Instead, we left it blank with a TBD, a label, a parameter. That when we ran copy array and manipulate, that's when we inserted the actual specifics of what we wanted to do. What, Michael, did we call our parameter, our placeholder, our TBD to be filled in later?

[00:14:35]
What do we call it in copy array and manipulate? Instructions. Instructions, spot on. And what do we call our one for the array? Michael? Array, array, well done. Yeah, exactly, array and instructions. People that allowed us, but notice, it's a bit of a flip, we had array position 0, do you remember earlier we had array position 0, which was, let's say 1, and then we multiply by 2, operators are like funny little functions where they almost take in the stuff on either side, right?

[00:15:12]
We're now saying, take this bit and run, wrap this bit up and throw the 1 into a function that does that work, and then output the result. Because if we want to pass functionality around in JavaScript, can we just pass 2 around? Uh uh. How do we wrap up functionality work that we, instructions that we want to have done in JavaScript? There are always certain things that I end up going on and on about because they're on my mind at a certain point.

[00:15:32]
What is, so, what is, how do we wrap up functionality that we want to pass around in JavaScript, in this case, we want to pass in as an input when we run copy array and manipulate so we can leave TBD a portion of the code. How do we wrap up functionality in JavaScript? Everyone together. Function. Yay, very good, hold on, everyone.

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