Check out a free preview of the full JavaScript: The Hard Parts, v2 course
The "Arrow Functions" Lesson is part of the full, JavaScript: The Hard Parts, v2 course featured in this preview video. Here's what you'd learn in this lesson:
Will diagrams how anonymous functions are used under the hood when an arrow function is instantiated. The drawbacks of using arrow functions on overall understanding and readability is then discussed, and a question is asked about whether there are memory considerations when using an arrow function is asked.
Transcript from the "Arrow Functions" Lesson
[00:00:00]
>> Will Sentance: But for now, I actually want to add something here. I want a little bonus here, related to what we just saw. I want to introduce arrow functions, a shorthand way to save our code. Let's have a look at this here. We've got our original function definition up here.
[00:00:16]
We know it's a function because look, it's got the beautiful word function at the front. That is, in my view, really readable. I know exactly when the function's showing up. It's got a body and it's got a parameter. That when I end up running multiply by two with a bit of three, it's going to insert three into input.
[00:00:33]
Three by two return out six into output. There are other ways to save functions. Let's look at the next version down. Each of these ignore the fact that we read acquiring a console our way through. This is not the individual files of code each time. Next line down.
[00:00:50]
We now here declare what's known as an arrow function introducing ES6. Remember function definitions can be stored, assigned to labels. Because they're just objects behind the scenes, and that's exactly what we're doing here. We are taking that function there on the right hand side and storing and label multiply by 2.
[00:01:08]
It has some differences under the hood for all, but for our purposes here for now, let's just put this here. That second line down there we declare, multiply by 2. There it is. And we assign it a function definition. There it is, no change. Now I will say this, let's just just like up here the parameter name is input.
[00:01:34]
You know, let's put it here the blue being a bit more focused. The parameter name is input. But nothing has changed in that second line. Well, the designers of JavaScript love to reduce code. I like to think of this as being a desire for legibility, but maybe not for readability, legibility.
[00:01:53]
This makes it nice and short and less stuff written. That is makes it more legible. I can kind of literally there's less to read and it sort of prettier on the page. But it may reduce readability. It will be like I'll say in a second. But why? But let's look at this next line down here.
[00:02:08]
This next line down here. Here we declaring multiply by two. We got a parameter input. And then what's this thing happen on the right hand side? Well, if you will function only does one thing and that is its return value, its output. JavaScript designers said, you know what?
[00:02:28]
We'll let you actually skip the curly braces and the return keyword and we'll insert those for you. We'll insert those automatically. And so this next line down here, Parameter input, arrow input by to JavaScript behind the scenes, when we run that multiply by two function is gonna insert.
[00:02:46]
The Return key word in front of input by two. We'll see that one in a second. Look at this one below. We can even remove if you've only got one input, the parentheses. I just literally say multiply by two is that function definition, that bottom one. But in terms of executing we'll see its changes in tomorrow morning or tomorrow afternoon.
[00:03:08]
But for our purposes right now, nothing has changed in that final version. The point I wanna execute that final version with the parameter input. And then return input by 2 as its body, just to make sure we know that nothing's changed. So let's actually execute that final one there.
[00:03:24]
Let's do it down here. Let's declare Toward, let's clear the left hand side of that final line. There we go. And I multiply by two functions. We're using the very last version here. We're using that very last version, not even any params no curly braces, super legible. And I tell you in a moment why question it's honestly it's readability in terms of its meaning to the reader.
[00:03:49]
Because there are many folk people will be watching this going that's the same thing as at the top. I mean, it's an under the hood changes for how we use it but not at this point. And yet it's essentially the same. So yeah, Todd. Let's now use the left hand side there.
[00:04:04]
What are we declaring first?
>> Speaker 2: Constant output.
>> Will Sentance: Yeah, excellent, and we've gotta go ahead now and run what function?
>> Speaker 2: Multiply By2.
>> Will Sentance: MultiplyBy2, and again, people, just be really clear, we're running the very bottom one, with the input of what, Todd?
>> Speaker 2: 3.
>> Will Sentance: 3, brand-new what, Todd, any change, no, brand-new?
[00:04:22]
>> Speaker 2: Execution context.
>> Will Sentance: Execution context, it is what it is. There it is, brand new execution context, and into we go. What's in our local memory, what's the value passed into our local memory first, Todd?
>> Speaker 2: Input, value of 3.
>> Will Sentance: Value of 3 assigned to what parameter?
[00:04:38]
>> Speaker 2: Input.
>> Will Sentance: Input, any change yet, people?
>> Speaker 2: Nope.
>> Will Sentance: Nope. Now, what's the body of that function? It's a stuff on the right hand side of the arrow with an inserted word. I'm going to do in, I know, I'm gonna do in purple here with what inserted word, Tom?
[00:04:54]
>> Speaker 2: Return.
>> Will Sentance: Return in front of what code?
>> Speaker 2: 3 times 2.
>> Will Sentance: Yeah, input by 2, which is 3 by 2, which is 6. And that is then return out into output and there it is. You maybe watching and then go, yeah, I knew that. But I think let me see that stuff down there, input arrow input by 2.
[00:05:21]
And it looks so similar to an assignment, by the equals sign, I promise you people are seeing that right-hand side there. And not realizing that is a full function definition, with a parameter and a body, with a return statement inserted automatically for us, okay? Would you do something in a second is actually let's have a look at this in practice.
[00:05:43]
So look at this, I've taken a higher order function and callback function from just before. And you see I've changed the function multiply by 2 into the arrow style. Has anything changed? Nothing's changed, I take that code I insert it. In, I use it as instructions, I would take a reposition zero which will be the number one on inserted into instructions.
[00:06:08]
Which is inserting it into everybody multiply by two. One is going to then be in the well one would be in the local memory of the input parameters value argument and. And then we do 1 by 2 and return out 2 into the execution context of copyArrayManipulate, and push it into output.
[00:06:28]
Nothing has changed here, folk, but you're gonna see this style more and more. And it gets even more, Extreme you probably know what's coming, have a look at that. This is what you end up seeing a lot of the time, given that I'm saving the multiply by two function here in global.
[00:06:50]
And then just grabbing it referring to it as Dan said by his label to pull it into copyright manipulate Developers go, you know what? Might as well just skip that step, might as well just take the code and insert that in directly. Given that we don't use the label multiply by 2 inside of the execution context of manipulate.
[00:07:12]
We just use the code And give it a new label instructions, why even bother giving it a label and inserting it? Why not just grab the code and just use it inside? And that's exactly what happens, but when you see that line of code there, we are so tempted to feel that.
[00:07:28]
That function is being kind of executed right there and then it's so unclear what it's doing. But that there is the full function definition of multiply by two, which is that function definition up there. Nothing has changed in reality. That function definition we know we grabbed by name and inserted engaged the labor instructions.
[00:07:49]
Nothing's changed. We've taken exactly the same situation, and we've now just inserted the whole function. I could take this input arrow input by two and it's just this code now inserted directly. All right, if you wanna have thumbs on this, you're gonna see this a lot and I'm gonna give my view on this approach in a second.
[00:08:09]
But you lost me. I'm clear clarification of really interested in anyone's clarification on this cuz this is a challenging shift here. Okay, we're not gonna tend to use this style too much today, but this is increasingly A standard style, why nobody use it too much a day. So, anonymous in our functions, they improve immediate legibility of the code.
[00:08:31]
It makes it look like kind of pretty, right? I'm not storing stuff separately. Why am i so when i'm doing hard parts? Why do I, Like declare function separately, when in reality will tend to just insert them directly. It was a rhetorical question, but okay, Kyle, go ahead.
[00:08:48]
>> Speaker 3: You might have another function where you want to pass.
>> Will Sentance: I love that, that's a very good reason. For me, I'm sort of talking in a more I guess, pedagogical sense, I do it because while this improves legibility, we write less code, it looks prettier, perhaps. And therefore it is very standard.
[00:09:03]
And I'm very standard and full endorsement of it, in terms of when I'm explaining these concepts. And that's a good predictor of whether it's readable in a sense of understandable and comprehensible for the developers. And by the way, this is not me saying that you shouldn't do this.
[00:09:16]
It's very standard, it's absolutely border line better practice. But in terms of our understanding. In terms of deciding how it's actually working, I would distinguish between legibility and readability. How this is understanding under the hood, how is this working under the hood is vital to understand what's really happening.
[00:09:34]
That function, whole definition that's being passed in is much easier to track that that's happening when we've declared it by label. With the key word function and then pass it in. And that's why we're going to continue in hard part today, to mostly use the keyword function. And this design here, this little shorthand version of functions, is really, really nice for legibility when you're passing little mini functions.
[00:09:58]
In is the input to other functions there is really readable and fully endorse and I would absolutely you know, you will see there's a standard. But it's not automatically the case that we should always be using arrow functions. And we'll see you later on situations in which you will completely under undo what we're trying to achieve.
[00:10:16]
There is an under the hood change to how arrow functions treat. This key word assignment that we're going to see in our courses and prototypes session where it can be really useful. By the way, I tell you this little preview now if he was a function inside a method, that lexically scoped arrow function was he was a Toronto where I can be really useful.
[00:10:37]
But if you're using that for regular methods on objects, It ain't gonna work. So we're gonna continue to default to the function declaration style. But, for when we're parsing little baby functions in, I do endorse that that makes it, that says map array 123. So we take each element, and multiply it by 2.
[00:10:55]
And see that one in one line? That is pretty nice, I do like that. But in understanding how it's working under the hood, it's important ever more to understand what's really happening here. Okay, Jason go ahead.
>> Speaker 2: Is, [COUGH] excuse me, are there any memory or memory allocation savings for that strategy of inlining.
[00:11:15]
Where you instead of creating an external global context for A function to store multipyBy2 in memory.
>> Will Sentance: The thing with that, Jason, is just that we're talking here about such small memory gains or losses at any point. We don't live in the world where we're constructed on that sort of thing.
[00:11:32]
Now, if you were calling that function recursively, if you were, and we'll see tomorrow in class in prototypes. Saving a 100 functions to 1,000 objects where each of them is copied. Where we could just have one set of functions and point all to that same set of functions.
[00:11:47]
Yeah, that's where performance counts, this sort of thing here it's so minor that we don't need to worry. More and more the most valuable resource as a developer, is the developer's time and ability to reason about it. Versus do we end up automatically garbage collecting and therefore, in the moment saving some memory?
[00:12:05]
On these marginal cases, readability comes first. That being said, as long as you understand how this is working here, passing in that function directly? I think it does it really nice. Mapping, 1, 2, 3 by this mapping rule, where it's explicitly in that line I think people don't know how it's working.
[00:12:24]
But I think people get a sense, they can make it work if they don't understand how it's working under the hood. But we wanna be those people who understand how it's working under the hood, and hopefully now we do.
Learn Straight from the Experts Who Shape the Modern Web
- In-depth Courses
- Industry Leading Experts
- Learning Paths
- Live Interactive Workshops