ES6: The Right Parts Arrow Function Variations
Transcript from the "Arrow Function Variations" Lesson
>> Kyle Simpson: I wanna talk about various variations. We've already seen that if you wanna make yourself an empty function or an empty parameter list, you're gonna have to use some sort of placeholder. Typically somebody will use something like the parenthesis, the open and close parenthesis like we see here.
[00:00:19] You also might see people just put in a placeholder variable. Now I really hate that people use the underscore as that placeholder variable. They also like to do it without any spaces to suggest the idea that this is a variable that I don't care about. So I'll just use this placeholder underscore variable.
[00:00:37] Some people like to use X as their placeholder variable. X is definitely better than the underscore, that's especially true if you're working with the underscore library. And if you're working with underscore or low dash, please, please don't use underscore as your placeholder variable name. Unless you're trying to confuse people.
[00:00:56] Unless you're trying to create visual hiccups. If your goal like mine is to create more readable code, please avoid those sorts of tricks that cause more problems for the reader. So when the case is that we have one variable that we either need or we don't need. And it's a simple lexical identifier, we can just simply list it there without any parentheses out.
[00:01:21] There will be several additional features that we're going to talk about throughout this workshop. That ES6 affords us the capability to do more with our parameters. There is, as a matter of fact, three. There are default values, spread, and destructuring. These are three different sorts of things that we can do with our parameters.
[00:01:38] We're going to talk about each one of those. So don't worry if I just started speaking Greek to you but in all three of those cases if you use any one of them or combination of those three. Even with a single variable you're going to have to put a parentheses set around it.
[00:01:51] So if I use the dot dot dot for example the gather operator on my parameter. I got to have parentheses set around it.
>> Kyle Simpson: So there's our first set of variation is that we can either see open close parentheses hanging around. And by the way open close parentheses the problem with that as your placeholder of your parameter list, looks an awful lot like a function invocation.
[00:02:14] So people see that and they normally think something just got executed but wait no this is the parameter list. So see there's already more visual hiccups than what we had before with writing out the word function. So any one of our nonstandard things also if you're going to have multiple variables.
[00:02:35] Like for example X and Y. And your arrow function is going to do something perhaps with the X and the Y. If you have multiple parameters they have to be surrounded by parentheses. Little side note, this is not standard yet there is a proposal, to have what's called headless arrow functions.
[00:02:54] Meaning if we don't need a parameter list we can just completely leave it off. That sounds awesome, until you then realize that's yet another variation syntax, or somebody's have to backtrack visually to say wait a minute. Was there a parameter list, or was there not? Because they're gonna see something like this.
>> Kyle Simpson: That's not confusing at all to anybody, is it? So we're already starting to collect quite a few of these syntactic variations were not done. All right so multiples, zero or nonstandard parameters are gonna have to have the parenthesis set. Now let's go to the function body. The function body in this sense is called a concise function body.
[00:03:41] You notice I'm just doing the constant three here just to make it easy for me to type over and over again, so I don't screw my self up. But it's an expression not a statement in the concise form it's an expression not a statement. Meaning all legal expressions are legal as function as arrow function concise bodies.
[00:04:24] Because I would really like for try catch to be something that I could wrap around the body of a concise method, of a concise error function but I can't. Cuz try catches is a statement. And if you have a statement you're gonna to state, you're gonna have to wrap your statement in a curly brace pair.
[00:04:39] So if I needed to do something like for example try catch. Now I know this is silly with my 3 example but just to keep things. That's not valid, so unfortunately I'm gonna have to put a curly brace pair around it. But I'm gonna have to remember that that thing's a statement and it's not valid.
[00:04:58] Other examples of places where I've wanted to do this, if statements, for loops. Those are all statements that it might be nice to have in the concise form. And by the way, we do concise if's blocks all the time. Where we put if, if, if and that's totally valid and totally legal but it's not valid is the concise body of an arrow function.
[00:05:17] Because these are expressions not statements. So we have to wrap that curly brace pair on it. Now let's talk about what that non curly brace pair is doing for us. It's implying a return keyword, this is implying that the value three is the return value of this function.
[00:05:33] Guess what happens as soon as you put a curly brace pair on something. No more implied return. So you're gonna have to remember if you run into one of those cases where you get a wrap a curly brace pair on it your'e gonna have to remember, oops! Got to go back and put my return key words in.
[00:05:46] Yet another set of variations. So now if for whatever crazy reason you need to have some curly braces around a thing you're going to have to remember to go put in that return inside of your block. Or it's not gonna get return there's no implicit return. Yet another set of syntactic variations that somebody running through your code, they're gonna have these visual hiccups like, wait, why does it need a return here and not a return here.
>> Speaker 2: If you have a single parameter, can you still put the parentheses around it?
>> Kyle Simpson: It is legal to still put the parentheses around it but the ES6 aficionados will jump out of the shadows and sneer at you. Why do you put those parenthesis? You don't need parenthesis, don't you know you can leave off parenthesis?
[00:06:30] They have jumped out at me before, so I'm just warning you. They're there, they're in the shadows.
>> Speaker 2: But if you want to return an object then you're
>> Kyle Simpson: We're not done yet, you're absolutely right. I love that my students always like to be a half step ahead of me that means I'm done exactly what I ought to be doing as a teacher.
[00:06:48] So what happens if the return value that you want to return. Saying needs to be an object.
>> Kyle Simpson: You can probably spot the problem here. The curly braces there are not going to be treated as an object value. They're going to be treated as the curly brace pair around making it not a concise body.
[00:07:11] So if you want to make it a concise body you might think I can just do another curly brace pair but no no no. You have to put parentheses just around the body to be able to return an object value.
>> Kyle Simpson: A lot of different variations here. In my opinion the variation in syntax is a detractor from that overall value proposition that we seem to be making.
[00:07:43] That, my God, I'm gonna write code that's so much cleaner and readable cuz I don't have to write the word function, word return and all those crappy curly braces and all that other stuff. If that's a value proposition we also to make an apples to apples comparison, have to also add in the negatives.
[00:07:59] And the problem is a lot of people only talk about the positives. So I want you to make an informed opinion, holistically, on the whole issue. The choice that we make to write these arrow functions does kind of take us down this path of, but what about readability.
[00:08:17] Now there are a few other things that I want to point out about the arrow function. I don't want to draw too much on this because it's one of our not right parts but I do want you to understand arrow functions. A few other things to point out about the arrow function.
[00:08:31] They are anonymous. They are syntactically anonymous there's no way to give a name to an arrow function syntactically. You can't put some extra name there before or after the arrow symbol or something like that. Now most people have probably not thought too much about well what difference does it make if it's a name function or not?
[00:08:56] Let me give you some examples of places where named function expressions are actually a lot better than anonymous functions. Any time your function needs to make a self reference to itself, typically that's for recursion. But there are other cases where your function might wanna make a reference to itself.
[00:09:11] For example an event handler that needs to unbind itself after it's run once needs a self reference to itself. If it's an anonymous function you don't have a convenient syntactic self reference. So you're relying upon some crappy outer variable that might be pointing to the thing. Another example where anonymous functions fail is the fact that anonymous functions show up as anonymous function in stack traces.
[00:09:36] So we see stack trace with 12 lines of anonymous function. And we're in minified code so they all say line 132, character 32,712. And we have no idea what that is.
>> Kyle Simpson: So if you've ever had a debug stack trace with anonymous functions, you know that anonymous functions are less helpful than if the function has a name.
[00:09:57] And if it's not just a name like foo but a good useful name like, Handle clicks. Now you start to get in your stack trace a more reasonable idea of what it's doing. So there are downsides to using anonymous functions. Now the astute in the audience is going to think, I've heard of this thing.
[00:10:14] Anonymous functions get what's called name inferencing. Say I have this, I have a var foo equals and I do one of these arrow functions, like that. It's an anonymous function expression assigned to the variable foo. If you run that code, and ask what is the name property of it?
[00:10:32] You are in fact going to get the string foo. So all of a sudden it start to look like this isn't an anonymous function, it's a function with the name foo. That's called name inferencing. There's a about a half dozen rules in the spec for how the spec can make a guess.
[00:10:50] And inference as to what name you probably want to refer to that function by based upon where that function expression gets saved. Okay sounds like our safety net right? Sounds like okay great I'm going to have all my arrow functions but they're going to be non anonymous because they're going to get name inference.
[00:11:08] Except the problem is 99.999999999% of all arrow functions you're ever gonna write are gonna be arguments to some function call. Like for example,
>> Kyle Simpson: Like that. This is the one case in syntax where it doesn't have any name inferencing cuz how could it possibly guess what you want to call it.
[00:11:31] It doesn't know what the parameter name of the foo function is necessarily so guess what happens? It doesn't name inference in this case. So in all the places where you're probably going to use error functions. You're probably not going to get name inferencing like you think. So they're gonna stay perpetually, syntactically anonymous.