What do you want to learn?
Skip to main content
by Aaron Frost
This course examines in detail the new features which will be available with the release of ES6, and provides clear and practical examples of their use.
Start CourseBookmarkAdd to Channel
Table of contents
Proper Tail Calls, Declarations, and Rest Parameters
Proper Tail Calls
Proper Tail Calls: ES5 vs. ES6
(music) So we've got LET definitions, we've got LET with looping. Those are the two pieces we're going to cover. There used to be three pieces of LET or sorry four, but they cut two of them out. So there used to be LET definitions and they cut out LET expressions and LET statements. Okay and if you guys want to come talk to me on the break about what those were, those were invented by Mozilla I think. And with block functions we don't need them anymore. Okay, so let's talk about LET definitions and then LET with looping. So LET definitions. This is LET like in its most basic form. Just like that, okay. So instead of VAR you'll use LET. So you literally use it just like you do LET. There's not a lot of differences. You can reassign it, just like you can VAR. So I can declare foo, assign it to 2, and then I can say foo = 3, we're good to go. So it's not constant, it's just like you use VAR, it's just a different word, okay. And this is also LET in its most basic form. We've already seen this code though, the only thing that changes is the word LET, now who thinks they know what's going to happen? Any ganders? Error, 2, 3, or undefined? Anyone? No one's willing, liken I burnt you all on the first one, huh? Error, wouldn't it actually be nan? Nan, yeah, undefined plus, it could be nan, yeah it's going to throw an error though. It's going to say bar's indefined. Because inside the left scope on the if, it actually blocked your LET inside your bar inside there. So the bar variable is now trapped inside your if statement and you can't access outside of that scope. So it's kind of, this is what we thought it was going do right? We did this with VAR and this, it didn't do what we thought it was going to do, remember? But now it is going to do what we think it's going to do, so that's nice. Oh so we have block scoping again, if you look, if you run this code, does anyone know what they thinks going to happen? LET A = 0, A = 2, what's this going to log and what's this going to log? Anyone know? Yeah they're going to log what you thought they were going to log. It's not a trick anymore, like I'm passed the tricky stuff, that was the variable hoisting. It runs like you think it's going to run now. So you're like, yeah this is what I always wanted, right? You didn't know you needed it until today, but yeah this is what you always wanted. This is what you thought you had all along, so you didn't really miss it. So this is actually going to throw an error though so if you say LET A = 0 and then you make another A with the LET declaration, it's going to die, you're going to get an error. The same is true for VAR if you use restricted, yeah, you can't redefine, you can't double declare those. You can only use it once. So did someone say something? So yeah, so without use strict you can do this with VAR so, you know, don't ever do that, but you could do that. Like it wouldn't totally die. But with LET you're going to get a syntax error and even if you declare a VAR then you do a new LET with C, you're going to get the same thing saying, that variable's already exists, so. So yeah, and these scopes exist across the board, so B is going to be trapped inside here, this LET C's going to be trapped inside this switch statement. LET D is going to be trapped inside of the while loop. So you're curly braces are your new scope, cool. Any questions about that? There's a question on the chat. Yeah, so what if you double declare LET and VAR, like if you do VAR twice it just uses the same variable, what happens with either two LETs or a VAR and a LET with the same name? I already answered that, I'll do it again. Just show the slide then. This is what happens, yeah at the bottom there, if you double LET it freaks, if you declare it with VAR and then LET it freaks, I'm not sure what would happen if you did LET and then VAR, but like who cares, right. Like you shouldn't do that anyway, so, right, okay, sorry about that. There was another I don't know if this is a comment or a kind of a question, but so LET works everywhere VAR works and VAR works everywhere it has worked? Yes, okay. And in all the same ways that it always has worked, yep. Good way to put it. Okay, so we have this thing called the temporal dead zone, and you guys know that some Dungeon and Dragon master freakin made that term up right? Like it was not like a normal folk called it the temporal dead zone. So we have this thing called the temporal dead zone temporal and I'm going to try my best to explain it. So look at this code, I'm using log a = 1, I'm trying to log it before the LET statement happens. What do you guys think's going to happen? Error? Error? Anyone think it's going to log undefined? So Firefox's implementation currently has got a bug, this is the reason I'm pointing it out, because you guys might get in there and play around with it and it's going to work differently then the way I'm saying. So I wanted to point this out. So Firefox is going to log a zero or an undefined here, okay. But with the concept of the temporal dead zone, it should throw an error, okay. Like you cannot use it until it's been declared, officially. So under the covers though the reason that they came up with this crazy concept called the temporal dead zone is because they still are going to evaluate it when it evaluates this function, when the evaluates do something, it's going to go let me evaluate this, I see you've got a LET there on line two. I'm actually going to reserve a spot in memory for that, but you can't access it. That's called a temporal dead zone, you can't access it until you declare it Does that make sense on what the temporal dead zone is? But what, what if there was a global A, what if there was an A in the global scope? It should log that A, but there's bugs like in all the implementations right now. But that is, that is a solid question. And I found that one out, like so I you have like an A up at the top and then you had a function with an A in it and you tried to use it before you tried to log it before it was declared. It should go up and get the top one, but all the implementations right now just log this undefined one that you're coming up on. Oh, yeah well they don't respect the temporal dead zone, yeah. So yeah. Okay, so it does kind of hoist it to reserve space in memory, but you can't access it until it's there. So and it would actually, it should throw a reference there. If you do this in Firefox it won't, but it should. Any questions on LET before we move on, we're going to get into looping, it's similar but yeah, go ahead. We have a few of them here. Do you think we should only use LET or is VAR still useful? I mean if you're starting a new project I would only, like okay, so if you don't have to support legacy browsers, like you're the sasquatch, like the mythical thing that doesn't have to support legacy, right. Like so if you don't have to, then yeah use LET or you're a no developer, then yeah use LET. I would, because it makes your code way more predictable, I think. Like it runs, going back to that statement, your code has a lot less to do with the way it looks than in the it executes when you're using VAR. So I would definitely use LET if you can, so. Then the next two questions, can you use LET in a for loop? Yep that's the next section, okay. And then when can I use this again, I'm guessing it's asking when is it available, oh when is it available? We'll talk about that, let me get to that too. We'll get to both of those, okay? Okay so that was looping it's pretty simple, so look at this code, one's going to log a 10, one's going to log a reference there. So specifically you're looking at these lines of code. So in the first for loop I use the var I, okay. So that means it sat here and in it incremented i until i was equal to 10. And when i was equal to 10, it didn't run this anymore, it stopped, right. So here it logs 0 through 9 and then once it was equal to 10 it stopped. Down here your j, it went and did the exact same thing, once j was 10, I'm out. So it logged 0 through 9, but when you got down here i was still a thing because i, the i from the for loop had been hoisted out. So you could still reference i, but over here you're going to get a reference there because using a LET instead of for loop is going to scope into your for loop. Does that make sense? So that's everything you ever wanted so you could have two, you could use i twice. Who feels good now? Yeah you can do it. Go home, tell your family, okay. Steve W is so happy about that wow. So yeah, anyone else want to ask a question before, because I'm, I think I'm pretty much done. Oh yeah also anything inside of the for loop, I think this went without saying, is also locked beside the loop body, so. So anyway, constant, anyone ready to move onto constant or any more questions? Yeah. Two questions here, I don't if you did cover one of these but, does LET still behave the same in respect to closure? So like if I put it inside of a IIFV or something? Or like inside of an anonymous function? I think so, yeah, yeah it totally does. An anonymous function or an IIFV they're just a function. So it totally functions the exact same way. And then what's the other question? The next one is, are variables declared with LET hoisted within the block scope? So I talked about that when I talked about temporal dead zone. As far as us the developers are concerned, no, but behind the scenes it is, which is why you have the current funkiness. Behind the scenes it actually is going to, do you have a LET, it's going to reserve a spot in memory for it. And then, but you can't use it, you can't access it until it actually is declared on whatever line. So if it's, if it's declared on like line 10, you can't refer to it until line 10 otherwise you're going to get an error. Today you can refer to it before you get to line 10, which is a bug, but you shouldn't be able to, so. So yeah, good? What version of node supports LET? So if you run node, I think node 0.11, okay cool. Thank you, yeah, they're hidden behind the harmony flag all these features. So once they're in VA it's just, it's just there. So like if you wanted to use maps which we'll talk about in a bit, like it's there, you could probably use a map in node if you had the latest version, but if you wanted to use LET it's not in yet. So yeah proper tail calls is the same thing, good question. Question? One thing, can you use LET to assign a function to a variable? So let A equal a function? Yeah. Totally. Okay. Yep, let's, like when we said you can use LET that places use VAR, we were serious about that, you can totally do that.
CONST and Blocks
(Music) Alright let's move on to constant. This one is like wicked hard to grasp. Right, not wicked hard at all. So it's just constant, you use const a = 0, don't ever try and assign me again. You'll get an error, some of the implementation's currently just go, like if you tried to do a = 1 on line two they just like let you think everything's good and then you log it and it's like, I'm still zero though. Like I'm not one, like so they don't die when you try and do it, but when it all works they'll die. Like just trust me, it'll die. So yeah. Constant, not a lot of, like it, oh yeah and as far as like scoping, it behaves just like LET does, so it's lexically scoped inside of your curly braces wherever you go. You can't re-declare it either. Any questions on constant before I move onto block functions? That constant was super simple. Okay, alright. Block functions. These ones are cool and because of this, that's what like this feature called LET expressions LET statements, if anyone knows what those were, they're gone because of this. So like if you wanted to make a temporary variable and you're a clever developer, because we all have clever developers, we would just say, if true and put down some false block right? So because they're like yeah dude, they're just going to put down an if true and get a temporal scope. They're like, let's just let them lay down a new scope just for fun. So you just show like a pair of curly braces and do some stuff and you got your own scope on the fly. So that's block scope. So I'd imagine this is going to make the code look like of wonky and sometimes, like if you have three or four of these. I could imagine like a crazy pyramid of death out of this, but it's there, so, so yeah. So you don't have to do the if anymore or the if true and it scopes just as if you had done if true. We're all done with LET stuff, yeah. Question back on the const, do const have the same scope as LET? Yeah, yep, totally they work just like LET except for you can't reassign the value once it's been assigned. So. Do you assign a function to a constant? Yeah, I mean if, yeah I don't know why you would want to, but, just why wouldn't you want to? I mean like let's say you were like you know how we can monkey patch functionalities today in a prototype? I mean maybe, I don't know maybe you don't want to do that, maybe you want to make a function that you can't override, I don't know. I'm not saying you do, I'm not saying you don't though, like you might want to, I don't so yeah, good question. Good. Can you do a const on a function and so, const A = function? Yeah or something like that. Yeah. So you don't have to worry about somebody else accidently competing with those? Yeah. I mean in some, yeah you could do that. You could do that. Tots the goats, anyone, anyone else? Okay. So I'm going to let you guys try out LET and CONST, yeah, on blocks can you pass blocks around? That would mean that blocks are an object and no, I mean block is like code flow, it's not an object, yeah. It's not a function like a block is just a set of curly braces to scope off where you want traffic to go, that's all, that's all it is. So if you guys want to pull up, does everyone have Firefox installed, I asked everybody to get Firefox installed. So I'm going to go through this real quick and I'm going to have you guys try this stuff out. So if you go to the compatibility tables and we go to LET and CONST, these are all supported in Firefox, okay. They do have that weird temporal deal zone bug that I was telling you guys about. And then block functions, they're in here too, block level functions. And these are supported in the latest Firefox as well. So you should be good to go. So I'm going to pull up Firefox and I'm going to start stuttering because I don't know exactly how you guys want me to say this without being confusing. So like if I come over here and say, let a = 1, it'll work so, const b is equal to 10, oh, const, oh b sorry, anyway, yeah. So you guys can kind of dork around with it if you wanted to write like a function with like a block scope inside of it and then call it just to make sure that the block scopes working. Go ahead and do that. I want you guys to try a couple of things out and then we'll come back and we'll probably just move right on because we're kind of over on time. I want you guys to try these out for a few minutes so let's take five and pull up your Firefox, your console, and try some of these out just so you can kind of get use to how you're going to code with them, so. Along with Firefox or node or Chrome, you can also try and run some of your code in Traceur and if you come over to this table and you're like, dude Traceur's got it, wait that table was messed up. There we go, that's right. So if you're like, cool Traceur's got arrow functions or Traceur's got LET and you want to try LET, you don't have to open Firefox. You can come to the Traceur GitHub site and they actually have a live repl where you can use code in line. So I'm actually showing you guys a class, but if you wanted to be like, LET a = 1, and it's going to freak out down here, it's going to say, unexpected token LET. So I'm going to say, dude turn on experimental features and it says, oh yeah I know cool, I know what LET is. And if you're like, okay what about this? (working) Right? So you see what it did there? So anyway it's like live transpiling this into a thing that it's not the exact same, but it will hopefully act the same, right. And you guys, I know all of you guys would want to write your code like that anyway, but yeah they let you do that, so. So that's Traceur though and you can kind of, if you want to see what some stuff is going to look like, you can come try it out here on the live repl, it's kind of nice. Traceur is a command line tool though you actually would install it locally. And then you can add it to your build process with like a a grunt tracer. I started grunt tracer and it's super simple to use, but if you wanted to just try out live on line, this repol is probably the easiest thing. So in between sessions when you're trying this stuff out, feel free to just come out to this repl and try it again, anyway, so. Alright let's move on to did anyone have any questions while they were trying this stuff out or did they find anything wonky? No, okay. Why I asked you to use Firefox, one time I was talking about this in a presentation and someone like got really mad and sent feedback that I'd favored Firefox over Chrome and they were really upset that I had done that. And I wasn't, I mean, I wasn't trying to do that, just Firefox has got the stuff and you know Chrome doesn't yet so. I'm only asking to use it where it exists, I'm not trying to force you guys to Mozilla or anything like, use whatever browser you want. I'm just asking that you use it where it exists. So use Traceur or use Firefox, if you see Chrome, like if it's a feature that's in Chrome, go ahead and try it out in Chrome.
Rest Argument Rules
Spread Operator, Destructuring, and Arrow Functions
(Music) Alright spread operators. Quick lesson, these are not hard to grock, and you guys can play around with them. Well only take a few minute break and when we're done they're simple. So we have this array, right, and currently the way we pull pieces, the way we pull arrays apart is kind of manual, but this is kind of the impedes of what it does. If you log nums is it logs an array of nums. If you log …nums, it spreads the array out into its individual pieces and then it will log them individually, does that make sense? So in place it's going to kind of replace this with all the individual bits from here. So rather than logging an array with 1, 2, 3, you get the actual pieces individually. Like easier than calling apply or something? Apply? Like .apply or. OH I see what you're saying, yeah, no you totally, you totally could use this with call instead of an apply, right. There's some other use cases as well though, so like normally in the past when we've got this array, like I've got an array of things and I need to pull it apart. I manually go, pull that guy out and then I'm going to pull that guy out and I pass them in, right. But now with this thing I can just like throw them all in there and this guy only cares about two them, so it's going to, it's going to spread out all three of them, but it's going to ignore the third one, right. And you would basically get the exact same functionality, so. That's kind of a comparison of how we used to do it versus how we would do it now, so. Some example of what you might do with spreading. You can on the fly you can construct some new arrays so let's check out that syntax there. I've got a syntax with nums and a syntax with letters and I make a new array and I just spread out the nums and the letters into it. And then I end up with this new array over here, this read everything there, so. That's like an example of something you could do. It can be, you can spread out the return value from a function call, so like if I had this get nums or I don't know that thing like had to go to the local storage and get it or whatever. And then it returns that I can by prefixing with a dot, dot, dot, it looks like a wonkey method call, but really what I'm doing is I'm spreading out the result of that method call. So you could do that, like that's one way you can use it. And I spread it out into a new array that I assigned the B, so there's that. That's kind of simple, I mean I don't know what all to say. Any questions about it? Yeah Tony's saying this is like Ruby or Copyscript, totally just like that. I mean that's where it came from. When we talked about the TC39 adopting de facto standards, this is a typical de facto standard that other languages were doing, people liked, we adopted it, or we, EcmaScript adopted it for all, for its interface, for its API, so, so yeah. Can you use it in combination with structuring assignment? Hold on, totally, you could totally do that. Can we do that when we do destructuring? Destructuring is a big part. Okay. So let's cover that when we get to destructuring is that cool? So everyone take five minutes, try out some of this stuff, see if you can get it to work or break, see where it works better, see where it works worse. Try it in the Traceur Repl, I think it works in Firefox. Spread, yeah you're good in Firefox and you're good in WK, web kit, oh yeah well, I don't think that's true, but whatever. Anyway, yeah, try it out. EJS has it as well. EJS actually, EJS has implemented the most features, if you look at this table and you look who's got the most, Firefox, well sorry Firefox has the most, EJS has the second most. And EJS is a bit more crossed platform, so yeah anyway. Traceur's got a lot of them as well. A lot of these ones with high counts though they have all these ones at the bottom that are just like they extended the number prototype or the math prototype and they got 30 things kind of easy, you know what I'm saying, so. The array prototype stuff as well. So yeah. So I'm just going to try and try this out live if anyone has any questions let me know.
Old Way vs. New Way
(Music) This is how we used to do it, right, at the top of our functions we would we would have a person and we would call display person and display person would take the incoming person and it would store its name and it stored its age and it would make sure they weren't undefined or whatever. And then it would do something within display. Yeah? Somebody had a question on wouldn't an object reference be more declarative? It looks counterproductive at first glance. I don't understand what he means, can you do you know what he means? Maybe, on the previous slide there an object reference be more declarative? I could ask him to clarify? Yeah. I mean it could be, but not necessarily, I mean it depends on what you're doing. And again, part of this is probably preference, some people are probably going to not like the way destructuring reads and so they might not use it, but I really like it. If he asked that question and if he clarifies let me know. He says this example is cool, okay. Alright, so yeah this is how you normally would do it manually, right. You'd have your person object and you'd pass it in here and then you'd pull it apart and eventually end up doing something with it to make it display. And so this is kind of how we've always manually destructured our stuff in the past. We now just kind of have some sugar on it and we've spent the first few, you know, x lines of our code kind of mucking up the top of the function, getting all these things ready and making sure that they're not undefined. But now we can do it just in one line of code. So instead of having to pull it apart like this, we could pull it apart, syntax is easier, and we can actually, we can get it all in one line of code. Do you guys think this is more readable? Or do you think that was more readable? What do you guys think? I think that's more readable. You think this is? I do too, but some people are not sure yet. Some people are like, I don't know. So what about that way? Do you guys think that's even more readable to do it that way? So I know that I've got an object coming in as the first parameter, so I just throw it straight up into the methods signature. Is that better or worse? And then your method body is just display person only cares about that now, right. It doesn't care about, you know, pulling things apart or anything like, you can just like kind of put that all in the language, so. I kind of like this, I'm super excited about this stuff. So yeah for me this is, and seriously no one applauded, what the fetch? Maybe someone online did. We didn't hear them. Okay. The order here doesn't matter, so we could switch age and name. Yeah because there's no like explicit order on an object anyway, right. Just key value pairs, but yeah. Like if I switch name and then age, you'd still have a variable called name with the name value and a variable called age with the age value. So you can pass a variable and then also pass with a comma the object, it pulls everything you need. I don't. So like display person, I have x and then comma person and so you're passing in that too into display person. So let's copy this over and we'll get your question going. So what's your question? So I have like var x = something, I don't care. So I have in display person as x and then comma, or x. Yeah, yeah. Yeah until you're passing in like that. Yeah so that means I'm taking in whatever x is and x could be a function, it could be an object, it could be undefined. But this thing has to be an object, because if I give that like an integer and it tries to pull the name off of an integer, the age, it's going to freak out. And we'll talk more about how it's going to freak out. But it's going too actually, it's going to lose its stuff if I tried to, like if I tried to pass not an object into this destruction pattern, it freaks out. Yeah? Kind of related to what you just said, the question was what if it doesn't have a name property, does name come through as like null or undefined then? It can if you tell it to, but we haven't told it to yet. Right now we're just doing the happy path where, I'll show an example. I promise we're going to get to that, whoever asked that question, because it's a great question, Eric. Okay. Yeah so it's all done in the method signature and for me we're going to get into default values in a second, so you can like totally destructor and data proof the function, zero lines of code in. And I think it's more readable anyway. So, like your functions will be less cluttered and they'll have just more of what you care about. So I think this is the best, this is the most readable way for me. Like if I looked at a function I'd be like I know exactly what's going on here. So, like remember I said you could do default values as well. So like if I wanted to make sure that there was at least a name, like so if someone passed in a person that didn't have a name, I could at least say well at least put no name provided or if there's no age, at least put zero, don't let it be undefined. Like give me a name, like and so we can kind of get it all done up in the method signature. So when you couple those two, I think this is where it gets awesome and it gets exciting. So this is another way you could use it to like destructor your throw error messages. Yeah we have a question. Instead of passing an object as a parameter can you pass a variable and that references that object? I'm going to go back to the code, is that okay? I think that's what I was already doing. So I have a person and I'm passing the reference. Is this what he is asking, is that what the person was asking? Because. We'll see here there, they're a few seconds behind us. I don't know, there goes. How do you deal with a nested. Nested? Yeah nested. You're like three slides ahead, yeah, but that's a good question right. Because not everything's like one level deep, right. So we need to know how to do that. Good question. Okay. He said yes, thanks. This guy says ES6 shut-up and take my money, okay, I love it.
(Music) So I've kind of showed you how you would use patterns, let's talk about like the intricacies of the patterns. So if I tried to pull a, if I tried to pull a out of empty object it's going to throw. If I refute the whole thing and I try and pull a out of it and assign it to x, x is just going to be undefined, okay. If I try and pull a out of zero, I'm going to get undefined. As long as I've made the whole thing refutable. If I just refute a in an empty object, I'm still okay. And if I only refute a on zero, like I'm trying to pull a out of this primitive, but I didn't refute the whole pattern, then it's going to, it's going to freak out because the second it gets into this pattern it's going to try and treat it like an object, which is going to make it freak out. So it, you'd have to refute the whole thing if it wasn't an object, so. Was that too much? No, we're good? Because I got more, okay. So if we, so here on the first one we refuted the whole entire pattern. And we've said a, pull a out of undefined and set it equal to x, and if that's undefined then the default value is 1. So on that first line x is going to equal 1. Does everyone see that? We're good? Okay. On the second one I'm only refuting a, okay. So I've got the brace at the front, which it means it's going to expect what's ever on the right of the equal sign to be an object, which undefined isn't, so it's going to throw. Even though I'm trying to say, well I mean if it's empty, if it's undefined, you just make it 1. Well your pattern wasn't the kind that can like escape errors, you'd need to refute the whole thing if you're going to possibly get a 1 in there. And then again if you just refuted a single property on an empty object you, as long as it's an empty object, you're good to go, so. Good question. Diego says, do I want to throw errors? I don't know you may. If you're writing a framework it may be more important than if you're updating. They are asking earlier somebody was saying, it kind of looks like you're just refuting every object everywhere. Like. And the that's the thing, that's why I was like dude I'm not sure that the first time I read this I was like, explain to me when I wouldn't refute. Like it's just going to be like a pattern with a ton of question marks peppered in, right. Like why wouldn't I just refute the whole thing? And that's a good question, man. And they may change it in the next version because I think everyone's going to want it that same exact thing, I wondered it the first time I saw it and tried it out too. Yeah. Can you, I'm sorry I heard you said this, but can you have a default value if you don't refute? So. I mean. Can I have default, yes, let's look at it. Like your default value seems to imply refutable. Yes. So check this out. As long as the key was there so can I actually do this here? Let (working) Okay. So if I say, right. Oh okay yeah. Oh I'm sorry. (working) What the fetch? I don't know, you should be able to, this is, this isn't, I don't think this is a working implementation because this should work and it's not, so. So yeah, good question though. So just it work like, essentially like using the double fife, like if it's false it will just go to your false or is it only for undefined? I think it's just undefined, it's not falsely. Okay. Yeah. It's not falsely. And we'll get into default values in a second, so. We'll talk about what triggers that, that assignment expression. Does anyone have any questions about this, about these patterns with default values? So far we're good? Okay. How awesome is this one? Someone asked about someone asked about nested objects, what was your name? Kim. Kim. So Kim you asked about nested objects, so this is a nested object. So I'm going to highlight the stuff that matters. So we're trying to destructor so we said find the b property and pull the C out of it. That sounded bad. Pull the c out of it, but we didn't add any refutability to this, so this is irrefutable. So when we're trying to pull c out of that and it's not there, it's going to throw an error, okay. But that's how you, and maybe we can do an example, maybe I have another side where we do this. But if I wanted that to be forgiving, we could just refute that one piece and then it wouldn't matter what b is equal to, it would accept it because it's refutable. And then over here we refuted the whole entire statement, so you know nothing needs to be anything really, it will just, everything will equal undefined if we don't. I mean this whole site could be undefined and because we've refuted the whole side, we should be safe, so. And that's nested. I think I have some more examples of it though. Yeah, sorry, nested I skipped this, I even have a slide saying I skipped this, that I forgot that I wrote. Okay so if I want to pull out address and I don't necessarily want an address variable, all I really care about is the city, state, and zip. This is how you would do that. You would say, find the address and pull out the city, state, and zip out of it and make those three variables. So actually here I wouldn't end up with an address variable, okay. So yeah. Any questions there? Everyone see what's going on? So here, like as far as available variables I could reference, I'd have name, age, city, state, and zip. I wouldn't have anything else. Any questions? You guys all kind of look glazed over, so I feel like I'm not doing a very good job right now. I feel like I've lost you, we're good? Okay. It's good it's just a lot of, I mean it's like this is pretty straightforward syntax, but with all the question marks. With that last slide. The defaults like that one's kind of like I would need a minute to destructor that one in my head. Come punch me in the face and it will probably look better afterwards, right? Like yeah, I know, it's a lot to take in. So here's how I could alias the city, state, and zip again on the nested pattern. Did anyone want to have, ask questions, like I'm just going to show this just to get the look back, hold on. Because this is where everyone kind of was like, no, ES5 where are you, yeah, so. Alright still have smiles I'm going to leave it up here. Does anyone have any questions about what we talked about? Internets, did you guys get it? So that one lingering question I mentioned was Ben had asked can you destructor every property? Oh yeah, yeah, yeah, yeah. So can I like destructor with like a star? No, no, no, no, no. And let me explain why. So Ben was saying can I do this? Ben wanted to do this, sorry so we got person up there, var, Ben wanted to know if I could do that. And like just have it like throw all the properties from the person onto the current scope as variables. No, you can't do that. So yeah. You're welcome. Hopefully no one else wanted to do that, because I don't think that was a very good idea. But yeah so, so yeah you can't do that. Star is not part of this pattern, I know it's part of a lot of patterns, and we've kind of like we see star or we hear the word pattern and we're like, star, no there's no, there's no pattern, there's no star in this.
(Music) Last call for questions on destructuring, it's about time that we're going to try this out for a few minutes. What are the best benefits of array destructuring? Oh man that's a good question. Okay. So I've been meaning to talk about, like the specific benefits that we get out of each feature and I've been forgetting, so I was like, I told them to softball me the question if I forget. So destructuring doesn't have performance improvements, right. Nothing that I just showed you is something you can't already do. Do you guys agree? We've already, we've always been able to do what I just showed you, this is a sugar on top of the syntax though. Like it just makes it sweeter to see and easier to code and maintain and to just visualize. Does that make sense? So some of the things we've talked about do have some performance impacts and this may have some micro benefits or whatever the opposite of a benefit is. But I thing that they're probably negligible, so yeah. Do I like Diet Coke? Dude I actually I hate Diet Coke, I really do, but it's the only Diet drink he had. And so, good question though. Anyone else, any questions? Yeah you said that the question mark thingy isn't implemented yet, is there any? Is there anywhere you guys can try this out is what you want to know? No, also is there a timeline when? No. Is there. Geez. Next version of Chrome and 10 version of Chrome from the? I have no idea, but like yeah I didn't prepare this presentation that well. Like I don't, like I would've had to get into geers, or to Google's V8 bug log and see where it's at and then everything and I just didn't do that. It's slowly trickling out, when you get onto to the compatibly list the one, I mean like I said earlier. Some of them say green, but it's really kind of only partial. Like I told you earlier, Firefox claims let on this list, but it doesn't respect temporal dead zone, and it still has statements and expressions which aren't a thing. So it's like, is that a real implementation, should it be green, it should be like lighter green. Like you know how can I use if it's kind of implemented, it's a different, it's greenish. Like if maybe some of these should be greenish and destructuring is definitely one of those, but if you guys want to try it out real quick. So if we say var name, age, address = person, it didn't fail, okay. So that's kind of, remember I, okay so I wrote the chapter on destructuring like that was one of the first ones I wrote. And when is say first I mean it was like two years ago, okay. And the idea of patterns, I didn't even have the word pattern in the chapter. Like it wasn't a thing that I needed to teach people. And it kind of came up later and then the idea of irrefutable patterns versus refutable patterns was something that came on later and I was like okay, so throw chapter away, rewrite chapter. Like you know I had to kind of start over. And so these things are changing and this is an obvious implementation. Firefox or Mozilla I should say, probably built this when, remember I told you we talked about the ES4, ES3, stalemate. So Firefox, like they didn't stop neither did like Adobe they didn't just like oh well we're going to like sandbag our language. Like they're over there implementing stuff, right. You guys can go to Mozilla's Bugzilla instance and you can see like code commits on destructuring in generators clear back in like 2006 and 2007. So they were working on this stuff during those stalemates, they were still like forging ahead and adding new features. And it actually helped in the long run because now that they're having conversations about well how should destructuring work. They have some really valuable input because they've already implemented it. And so, like the destructuring that you're going to see in Firefox or like this one that we see in Traceur, they're not solid. So and then they're working on them, but it's tough, it sucks because some of the stuff you can kind of play around with, but we're still kind of, you know, cutting edge on a lot of this where we're not going to be able to mess around with a lot of it, so. But again, destructuring is mostly just the sugar on top of things you could already do in the language, so. Good question. Great, great, great, great question man. So okay. Alright do you guys do you guys want to try it out for a few minutes, maybe try some destructuring in a method signature? Go ahead and call method and destructor it's return value, see if anyone wants to try and destructor like a canvas byte array. Sound fun right? I'll try and do that while we're working. But if you also, if you want to read about them, and their refutable matching, here's two links that you can go to as well. They're just, if you just go to the Harmony proposals page there's one called destructuring and one called refutable matching. And if you just go check those out that is what you will use.
Arrow Function Syntax
Arrow Function Examples
Functions vs. Arrow Functions
Exercise: Arrow Functions
Default Parameters, Classes, and Collections
(Music) So some other ways to refer to default parameters because they call them like a million things and I don't know why. But like when you're going through the documentation I don't know if they've called it the same thing twice in the documentation is all I'm saying. Default arguments, default values, default function arguments, default optional parameters, any similar combination of any of the words used here or anything you that you could possibly imply also refers to the same topic. It's kind of a mess as far as the wording goes. And this is kind of a new version of the old scene, we've seen this before in C++, we've got them, Python's got them, Copyscript's got them and now EcmaScript's has got them too. So historically, like if we spend the first few lines of our code data proofing, right, and we've talked about all these things we do at the top of our functions. And data proofing's definitely one of them, right. Who's done this kind of stuff before this kind of data proofing, right? Because we can't get down into the internals of the function the lower lines if we've got like random undefines floating through. And invariably like once you get your first bug, how do you fix that bug? You just like go to the very top of your function, do down a line, and then you do this. Like so even if you didn't write it that way the first time, maintenance mode kicks in and you do these kind of things. You kind of data proof your stuff at the top of the function. So we spend the first, and depending on what kind of function it is, it could be, you know, quite a few lines, you know, data proofing our stuff. So I call it data proofing, that's not like a word that you should pretend is real, like that's just what I'm talking that's just me, that's how I say it. So sometimes we'll let, we'll use the short circuit expression some people will use a ternary example, I mean, it's up to you guys, you know, everyone's different and that's fine. So here's kind of, here's kind of how you'd use it. So we have this say, say hello thing and we've got a name and I'm going to give it a default of world, okay. So this function, all it does is says hello to you, that's it. When you call say hello you got to give it a name, if you don't, it's going to use world. So if I say, hello Diet Dew, which there is none around here for some reason. There's Diet Coke. Right, that's a little weird, but so, so yeah, so you say hello, you pass it that Dew, it's going to say hello Diet Dew, you passed it an empty string and it just says hello and the space, okay. You pass it, you pass it undefined, or you don't pass it anything, which is the same as passing undefined and you can see that here in these last two examples, okay. So what you can tell from these four examples is passing it an empty string, so it's not faulty, what triggers the assignment expression, okay. It's undefined that triggers it. And some people, like there was actually big conversation in the TC39 and they went back, I don't know if like it got physical, I don't think anyone got punched over it, but it was like there was like serious conflict where they were like, hey if I purposefully pass you undefined arguments.lenght it'll be 1. And if arguments.length is 1 and it's undefined, then I think you should trigger, you shouldn't trigger the default value set. That means I wanted it to be undefined. And some people were like, well that's a silly use case, like that's not a good use case for what we're doing here, so no. And that was kind of the generally, like those people, that was a good opinion to have, like that was a solid thing, like if I purposely passed it in, that's at least something to consider whether it's a good idea or not. At least they considered it and decided, even if you purposely pass in undefined, it's still not going to, it will still trigger it like. Even though you may, like you're trying to put something there besides undefined, like in your pass it, anyway. So yeah. Like it's not just the arguments.length is like not where you're at, it's, like if as long as the thing is undefined it's going to trigger that default assignment events. So empty sting doesn't trigger it and it's kind of important to know that, like again like I wanted you guys to know that falsly not's going to trigger obviously. So what does it give me? It gets you less code, right we talked about that, like you're going to be able to write less stuff. I think the code written with default parameters is easy to read. I've showed you a couple of examples today and just kind of cramming that stuff up in the method signature for me, makes a lot of sense, it makes some good sense. And it also gives you some improved predictability, like when you look at the function I think having it in the signature kind of tells you some of the stuff that's going to happen versus having to like read through the body and see all the ternary code about what's going to happen based on if it is undefined, it's another thing. I think it improves the predictability as well. So you can, you don't just have to assign it like to a static, a static value, you can, you know, assign it with a method call. So if I have a function that just logs the ID, and if ID is empty I can call getrandom and it will go ahead and try and generate some random function or some random number. Can you point it a reference to a function, or does it have to be executed function? So it is actually a call like that. Yeah. And you're not, it's only going to execute that method call just as if it was inline. So that you don't pass the pointer to a function, you pass it like what you want it to call. I get it, I'm asking if you pass it a pointer, is it going to throw an error? No, I mean it's the same concept as like. Oh yeah, yeah. Use strict, it's just an inline thing that. I got ya. That doesn't execute, so. That functions only going to get called if that parameter is undefined? Yeah, yeah, yeah, yeah, only on the trigger of it. Like that last slide, we talked about the triggers, how does it get triggered? And only on the trigger events is it going to actually call that. And I. I was assuming it called it immediately and then it just cached the value, right, because it's set up like a function call and you're giving it the return value, right? Yeah, yeah, yeah, yeah. It doesn't call it once undefined, when we define X it's not called once and always uses that value to call every time A is undefined when you called it. Yeah, no, no, no, totally, you guys, let's test, let's write this out real quick. So what he's saying is he figured it would only call the default value once as opposed to every single time through.
Exercise: Default Parameters
(Music) So let's call that up real quick that we, you know, we kind of have an example of how it's going to work. So let's say function, so let's give us a counter var counter is equal to 0, function getCount is return counter++. And then we're going to say function logMe(count = getCount). Just so you guys can see this happening every single time, actually (working) Okay? So yeah. Dude I wrote the word in there count like 10 times, I'm sorry. This is not a very good code example. So I'm going to call logMe and we'll pass it 10, it logs a 10 right? So if we say, logMe and we don't pass it anything, it said I'm getting the counter and it's zero, okay. And if we call it again, if what I'm saying is right, it will say getting the, it will log that getting the counter again, which means it's going to call every single time this triggers. And it did, so it said I'm getting the counter. So every single time that you've got a violation of that thing, it's going to go ahead and retrigger that event. Does that answer the question? Okay, are you happy that happens or does that bother you? I'm surprised? You're surprised? Mostly, right because I was assuming it's a static value, just like when you had a string there whatever, but I mean it makes sense. Yeah. It's just a little surprising. Yeah. Because that means they actually put in the logic in their, you know in their new parsing to say hey this is not a value, this is a call coming. Yeah, yeah it is actually executed as opposed to evaluated one time. And if you wanted it the other way you'd have to make a separate call before that, before defining that function just to have what the default is. And again if you don't like that, you know you don't have to use default parameters. I think that they looked at what are people doing most of time, let's do that. And I think most of the time people want that thing to run every time, so. That is, that is a good thing that you had us test though, because I actually didn't cover that, thank you. Yeah actually your slide there actually kind of does this. This thing? Just in a different way, right, because this is going to throw. Yeah, yeah, yeah, yeah, this is the same kind of idea, right? So one thing I wanted to show is that if you get an exception in your default, in the method that's triggered by the default assignment. It's going to kill your execution, so like it's not, it's not immune to exceptions. Like it's the same as if you put it inline and it got an exception there, so, so yeah. Edwardo shivers when he sees ++. My code just made him shiver. I'm going to take it as a complement. Okay, so does this make, I mean I have a method here called die, I'm like, it's supposed to die every single time. No matter how many times I called test, if I don't pass it something, it's going to die on purpose. So this is something you could do as well if you, if you had something that you needed them to provide you, you could have a die function if you wanted to. Where you're like, just give up on life, end it all right now. Tell them that they did it wrong, so. This is something you could do. I mean I'm, I'm not saying it's bad or good, it's just a thing, okay. Again they propagate the errors though. So it says assignment, oh yeah, yeah, yeah, yeah, this is a good slide, whoever wrote it was great. Anyway, so it says, assignment happens lexically. So I want to just kind of point out what's going to happen here. So I have a global X, right, out here and it's equal to, it's just a string, it's not important. It's an init. And down here we have this test function where if I don't pass anything in, it's going to say you're equal to X, okay. And then internally I have a varx and I say go ahead and return A. So test doesn't do anything besides it takes a thing and then like just hands it back, right. And then so when I call test and I don't pass it anything, it's going to go get x. So everyone here's like cool x is equal to init, right? But it's happening lexically. And inside this lexical scope, (sound effects) x is still undefined, okay. So it actually, it assigned it to undefined. And it's not going to like do this endless loop, so if you're like default assignment function returns an undefined, it's not going to just sit there and call it until it gets a not undefined. It's just going to call it one time, so. Does that make sense? Good, okay. Awesome. Okay. So yeah I mean again no, you know, x not a good variable name, use better variable names than that, but hopefully you're not going to have too many name collisions like this, but if you did this would be why. Not all parameters need default values. So if you're going to assign one you don't have to assign the next one. It is optional. So that's cool. And then you can't use default parameters with REST though. So like we've got REST here, right, we're if I call this function and I pass it 100 things REST will be that array of those 100 things. Whereas if I pass it, if I don't pass it anything or I pass it undefined, it's not going to let this happen like, you can't use this, it's going to give you a syntax error, okay. So don't try and use the default parameters with REST. If you had, I'm going to copy this real quick and show you, because I don't want to be misinterpreted. So if you had A,B you could still use it over here, you just can't use it over here. That's the only syntax error, okay, is to put it on the REST parameter itself. So you can use it everywhere else, just not on the REST parameter. Eye to eye, we're good, okay. Awesome. Is everyone online good? Okay. How long do you have in this section left? A few minutes. Okay, that's perfect. Okay. So another thing that's unique about default parameters, so when you have the arguments object like so let's say I called test and I don't pass it anything, like it wants an A, a B, and a C. So if I don't pass it anything A's going to be 1, B's going to be 2, C's going to be 3, so they're all three going to have values, right, but arguments.length is 0, okay. So just because it has a value, it's still not going to throw it into the arguments object. So if you're one of those wizards that sits there and checks incoming parameters versus the arguments object, and you know who you are, this may throw you for a loop unless you like that it does that, so anyway. So if I pass it 1, because I only passed it 1 A is going to still be 1, B and C will both have values, but the arguments was only 1 long, so. We're all good right? Default parameters do not show up inside in the arguments object. There was a question there right at the end. Can getCount have a reference to this? If so what would it be? Can getCount have a reference to this? I'm going to go to Firefox for this because it's actually implemented over here. So can getCount have a reference to this? I mean I think it's just a, I'm just going to say this, I'm not even going to try it out, it's just a regular method call. So it's whatever the this is, if you're inside of, if you're daisy chained off of an object call, this is the object. Anywhere else you're going to be the window, so, so yeah. I answered it that way. So we default, we defined default parameters from left to right I mean you can, I mean it's, if I implied that I apologize, let me, let me show this real quick. Like if I skip this one I can still do the next one. Like I wasn't trying to say, once you do one you have to do the rest, that's not what I'm trying to say. Just whatever order you want to do them in. Yeah I think it looks gross too, but whatever. Yeah like that doesn't look great, but you can do it. You don't have to, not everything has to have a default value, just only the ones you want SANS the REST argument.
History of ES6 Classes
(Music) I don't want people to access my Monster's health property like manually, I don't want them to be able to say, what's the monster's health, okay. So I want to have like this private property called health and if you want it you're going to have to call get health, you can't just say like give me the health. And I don't want you to be able to manipulate it because if you adjust the health I need to be able to react to that internally, right. And so I'm going to make, so by saying this sub monster health equals health, if you pass in the health in the constructor it's going to assign like some GUID on the this equal to health, right. So the reason that it's private is because you're not going to be able to predictably know what property belongs to what, you know what I'm saying? Did that make sense? And so, especially, like if you take this code and over here in the repl, so if you take this and you say, var a = new Monster, what's our Monster's name? Kevin, of course dude. His hit point's one, Kevin's not a very powerful monster. Come on Kevin. Why isn't it logging my stuff? Dude is my browser broken? How come none of my stuff's working? (talking in the background) Dude it's totally something not even working. Oh, there we go, my man's got, he's got my stuff cranked up so high I can't even see it. That was you Mark. Yep, always the font size. Yeah. Let how about var because we're going to put in a closer anyway. There we go. Now it logged my, the monster. So I have this monster and his name's Kevin and his, he's got some random property that's got a 1 in it, okay. And the only people that know what that property is, is us because when we declare our function and we need a private property like this, we're going to put it inside of a closure so that we're the only ones that have access to, we're the only ones that have access to that symbol. We don't want the world to be able to get, gain access to that symbol right? Otherwise everyone's going to know what it is, they're going to manipulator stuff. So if we just go ahead and we wrap it like that, then at runtime there's no like certifiable way to detect what's going on here. So if I say this.monster (working) what the crap? (working) So I should pull this back out. Okay got it. Ohh, sorry that was so painful. So this way everyone can see what monster is, they can all construct it, but they can't see any, they're not going to be able to know what my private variables are, so. Like if I had health and then maybe what's another feature of a monster? Horns? Right. Attach value. (talking in the background) Speed? Yeah, oh yeah, yeah, yeah, speed's good, I don't want other people like to be able to mess with my guy's speed right? Like they can maybe find out what it is, but I don't want them to be able to alter the value of that property. So that's kind of a thing that I would definitely want to use this for too, that was a good call. So when you new this up you can be like, speed, he does speed this monster, right? And then if we need to get this speed out we can say, get speed so we can use one of the ES5 getters or properties. We can say, return this sub monster speed, right. so now over here I can say a. oh I didn't pass it in. Who's Kevin? Kevin, is there a Kevin in here? Not a real person. I thought you were trolling someone, I thought, but it's not even a real person, who said Kevin? Yeah I thought is it a real guy? No. Just made it up. Ahh Kevin take that buddy. Kevin's like dude the monster's strength a million. No it's not buddy, it's not a million, it's -1 the speed. Anyway so that's how you implement like a private property, are you guys in love with that, you hate it, you love it? Hate it. Hate? Love? I don't mind much either way. Who's just happy they got something out? I'm just happy that they got something out. They made a way to do private property. If they agreed on something GUID generator, and if they agreed on this class syntax, and we can combine the two to get a privatish property, even if it's only private by obscurity. That's fine with me, I don't care. On the chat there's a question if you could just explain symbol really quickly. Symbol. I actually never, I haven't read the spec, I only know that this is what we're going to use it for, but let's go read it real quick. Actually let's come over here, hold on let me pull up the site, that's a good question. Harmony proposals, tone that back up a little bit, yeah it's not even on there, that's what I thought, I never saw it on here. So if you go to symbols over here, yeah he's going to take you over here and it's super easy to understand. Okay the symbol constructor is, what the fetch? The symbol constructor is the percent symbol, percent intrinsic object of the initial value of the symbol property of the global object, totally. That's what we thought it was, right? I don't even know that that means. Perfectly clear now. Yeah. When symbol is called as a function rather than as a constructor, it returns a new symbol value. That is, that's counter intuitive. When you call it without the new you get a new symbol value, that's cool, whatever. The symbol constructors not intended to be used with a new operator, okay that's fine. Or to be sub-classed, it may be used as the value of an extends clause of the class declaration but a super call to the symbol constructor will not initialize the state of a subclass instances. Anyone? Did that answer no one's questions? Yeah I think that answered nobody's question. But that's what it is, because it's not on the proposal site. So sorry to disappoint. For now I think of symbol as like a GUID generator that's never going to give you the same one twice. Can we agree on that? At least for the purposes of classes? So when you use it for a property name, I feel like I read that it's treated specially, like it doesn't return a string so much as it, like it makes a non-enumerable property as well. Does that sound right to you? So like if I, if I created monster and cycle through its properties the monster health would not show up in the list of property names I think. Maybe? I don't know, I don't think so. Oh, oh, oh, oh, oh, okay, yeah, yeah, yeah, yeah, yeah, so if I say this .get own property it won't be able to find it. Like so you know how on an object you can say, object .get own properties and it says hey well I've got a name property and I got one of these and then I got one of these, right. I got a speed and a health. Well if you use this symbol supposedly it's not going to show up on the get own property list so people won't even be able to like poke the thing and be like, hey what keys are on you? Like they won't know. So if that makes any sense.
Getters, Setters, and Class Properties
Additional Class Features
Collection Maps and Weakmaps
Modules, Promises, and Generators
(Music) Margins are hard to discuss, because there's not any great support for it right now, it's changing even like a lot recently. So no one's really had a lot of time to get in there and implement it, so a lot of the decisions are made and people keep saying, no and by people I mean the people who understand it. They're talking about how great it's going to be. It's hard to really show off though. Like in code because I can't really have you guys, like there's no way to like mess around with it. So it's really only available if you got Polyfills right now. It's still super fresh, like let me show you guys this, so this was our notes from June, right like they just barely met in June and made some fairly major discussions to it. These are their module breakout session notes. Like they made some changes, significant ones, even in June. So it is, when I say it's still fresh I mean it's still one of the one's they're still talking about and trying to make sure they get right. And it does have the least amount of tooling of all the other things that we've talked about. So who here's familiar with modules like CommonJS and AMD, we kind of get them, yeah, okay. So a lot of us kind of get them. They've got bits from both, both have their merits. When Dave Herman and company sat down to like spec what modules would look like, they came up with some goals and they wanted to make it similar to both. So it's similar to CommonJS in that it favors a single export. Like in CommonJS you can export more than one, but it really kind of lends itself well to that single export. And it also supports Cyclic Dependencies, so if A depends on B and you try and, if you try and, you know, import A and B depends on A, that's okay. Because otherwise you'd have like an endless cycle and that's something that other modules just needs a little support. But it's similar to AMD and that it allows, it has asynch loading support and configurable module loading, okay. So let's kind of talk about this stuff. The major design goals, like when they sat down and talked about them, they had a lot but these are some of the default ones. So default exports are favored, static, they wanted a static module structure instead of a dynamic one like we can get in other systems. And they also wanted the support for the synch or asynch and then the cyclic dependencies. So let's talk about each one. Import/export syntax, so there's two pieces inside of inside of that you really need to focus on. The one is the import/export syntax because as you're writing your code you need to export it and then you also need to import other people's code. But then there's also this programmatic loading API that they've built as well. So let's talk about these two things. Let's talk about the import/export syntax first. So if you want to do like this single export, like you write your class and then in your myclass.js you say export default myclass. So the word default is a keyword and that means when they import it, whatever the default is is what they're going to get. Like that's going to be whatever, the thing that gets imported. So if someone imports, if they were to do this, import myclass from myclass, that's what they're going to get, they're going to get a reference to this myclass constructor, okay. So that's kind of the basic import/export syntax. If you had some library and it was like hey export this constant square root math that square root, export the square function, and export this diag function, and then in main if you could import only some of if you wanted to only some of them you could. So if you were like, hey go ahead and import just square and diag from lib. And it would see lib and it would know to go ahead and asynchronously it would load that and go ahead and import those. And then you could, you know, square whatever you wanted to or you could call diag or anything. Does that make sense how you're going to import functionality from other stuff? You could also, if you wanted to, you could call import star as lib from lib. And then instead of being able to call square you'd have to call lib.square or lib.diag. So that's other syntax on top of it. So if you wanted an alias what you're exporting, you could say export myclass as dude and then you could import dude as bro from lib. And so you could alias them on the export and you could alias them on the import as well. Make sense? And bro is an instance of myclass, like if you were to do that it would work, okay. So Cyclic Dependencies, so import main from main and import lib from lib that would be like, if, no matter which one of these things you required, or that you imported from a third module, they would both sit there and have this cyclical dependency on each other, but that would be okay. Like it would load the dependencies or the imports first and then it would run them, so. And main and lib won't pass or? Come again? Are the pass or what? Yeah hey pass. Okay. Yeah, yeah, yeah, yeah. So they don't have to be with the same directory or in? No. Okay. Yeah. So here's like a different example that uses file paths a little bit just to kind of show it off a little bit better. So like in lib if you wanted to import, you could import the default thing or you could import some name things from my lib, like that's one syntax. You could import just the default or you could import just the name things, the properties on top of it. You could rename them if you wanted to, so if you were like hey import named one as my named one and then import named two as well, so. That's one way. Importing the module as an object with one property per import, so import * as mylib and then anything exported you'd call as mylib.foo and mylib.bar. And then if you only wanted to import the module, but not actually do anything with it, you could just, you just say import and give it the path. Because that might be a thing you want to do like a Polyfill, you know what I'm saying, or I don't know something. So that's an option. So here's how you export, you'd say export var myvar, export let, export const, you can export an function, you can export a generator, you can export a class. If you put the word default in there anywhere, it will, that will be treated as like the default thing. Otherwise this export class, you'd have to specify like, it would only be like a dot dependency it wouldn't be the main export, if that makes any sense? Exporting, you can say export *, so like I could re-export if that makes any sense. So like let's say I want to import something, like import foo from foo.js, and then I want to export it back out to someone else. You could just use this syntax, export * from some other module. So that would basically bring it in and go ahead and export all of its stuff back out. Awesome, weird, that's awesome. You can export foo or bar from that other module, like you could export just pieces of it if you didn't want to export the whole entire thing. You could and you could use the as syntax as you're re-exporting as well, okay. Can you maybe give a use case for that? For what the aliasing or the re-exporting? The re-exporting. So let's say that you were, you had some module that was like, I don't know some extension of the web socket object, like I showed earlier or and you're like, hey if I'm in IE you know, import this thing and export it out. I don't know, yeah, does that make sense? Yes. I don't know. Maybe you want to create a library and you want to split it into a bunch of different objects, but, yeah, and then you just, yeah, export them from one place. So you can just import that whole library into files, things like that. Yeah. Yeah, kind of, yeah I don't know I've never done this, I don't even know if it's possible in CommonJS, but I mean I imagine in CommonJS you'd just be like, require or var foo equals require foo. And then I could say, export that foo = foo I got, so I could re-export I've never done it though, so I don't really know. Yeah? Are the paths relative to the current file? That's a good question, I don't know, I could try it out, but that's a good question. So I wished I could have tried that out. I knew you guys were going to ask though.
Module Programatic Loading API
(Music) So let me talk about the programmatic loading API real quick. This is what it looks like. So you say system.import and you give it the path. And then it's going to go ahead and return you a promise. And when the promise comes back it's going to give you the module back, okay. So who here's not familiar with promises, because this is promise syntax here, this .then it basically makes asynch code clear, but you're going to call system.import and then you're going to, when it gets back, you're going to just call .then and it won't execute this function here until it actually goes out, gets that file, brings it back in, evaluates it, and then it will give it to you. Does that make sense? So and if there's an error you can also catch the error as well. But this is what the import API looks like. It's based on promises and the promises provide whatever was exported you can use promises to load multiple at one time, so you can be like, hey promises.all and then you can have just an array of file paths and you could do a map on it. And say system.import each one. And each one of, that map would return the promise. So you basically have an array of promises. And then you could put that inside of this promises.all you can call .then and then it would give you back an array of modules. Anyway, this is how you can programmatically use the loading API, okay. The loading API has multiple methods and some of them look like redundant. System.import and system.module, they both returned the module via an import I don't know the diff to be honest with you. I mean the source is a string, or a reference to the path. You can set one like if you created a module you could go ahead and set it, and then you can define one, which will eval the code, but not import it I don't think, I'm not sure. I wish I had better explanations though, yeah? I'm not sure if there is an answer for this yet, but there is a question on chat about if one of your, if one of the things you're trying to export, like say it's a, you know a relative path one, like the re-exporting. If it can't find that an import to export does it throw? Yes I'm guessing that, so see this system right here, this system.import. Yep. And then it does a then and catch, then is the success on the promise and the catch is the error on the promise. I'm guessing you'd get a catch on that. I think she's talking more like in the actual definition of a module, like if you went back a few slides, oh back in the import/export stuff? Like if you're trying to export from some other file and it can't find it. Can't do it. Does it throw? That's a good question. I would imagine that it throws. Anyway so this is the API import module set and define, again I wish I had been able to mess around with this stuff and give you guys better explanations. There is something coming in the future which is a module tag, which will kind of take place of a script tag and you'll just give it the path to the module that you want it to import. And you can kind of Pollyfill this thing by, there's a Pollyfill out there right now that will allow you to kind of get this same kind of functionality. So let's say we go ahead and import jQuery from our lib/jQuery. If we, if you go ahead and log the dollar sign as in this, that basically tests to see if this has the jQuery object in it. And for us the this is going to be the window, right. Because we import it in a module, it didn't actually put jQuery on the window, it kept it local. It's like localized to our module. So you know how it normally, anytime you import jQuery it clobbers the window with a dollar sign, like no matter what. This thing would like maintain it into your, into your module. However you can still talk to the window if you needed to and the module tag forces strict mode. So there's no, there's no preis five syntax in here, it's all, it's all enabled, it's all forced you to use strict mode in here, so, so yeah. Does that allow for multiple jQuery libraries? Probably, I hope so. But if you had like two sections of code that depended on different ones, you could just make them separate modules and then it doesn't matter, right. You could just import them, import one in one module and put the other one in another module and they don't care about each other. Yeah? So with that module take, how do you name the module? Like so you got a module take like, what if I want to use that module in a script take then like what its name or whatever? That's a good question, I don't know. Can someone write that down and we'll look it up? Yeah.
(Music) Promises, what problems do they solve, why do we need them? So async code looks messed up, right? Like it's not always clean. And when you like just get done writing like this perfect asynch structure like oh this is messed up. Like I shouldn't have done this, there's got to be a better way. Because sometimes, and especially like in jQueryvile, you end up with this guy. And who's ever had one of these? Like you're 18 levels deep and you're like, wait where did I define name and it's like 7 levels up and you know, your days get really sad. And maybe, you know, it helps with your code organization because some people are like, dude I do asynch for breakfast, like it's no big deal. I have two more for lunch, but your code looks like it's totally jacked. And promises are here to help us kind of make that stuff cleaner. And an example of something that's dirty, and this is a simple example, but it's like you're trying to load an image and you just want to see when it's done. You know what I'm saying, like all this asynch stuff. So I get this image and you get this loaded function and if the image is loaded, then just call loaded, but if it's not, add an event listener for loaded and then call loaded. And then I also have to have an error functionality. So it can just make the code for something that's fairly simple look really ugly. And if this was promise based, you could just say, image., you know, image.load.then or image.ready or something. And if that ready was a promise, then you could just daisy chain your .then there and be good to go. Like you wouldn't have to, you wouldn't have to deal with all this stuff, so anyway. It helps keep your code clean. So let's talk about the promises instructor, we'll talk about, so once I want to talk about how you construct, I want to talk about once you've constructed you have instances and then there's some static methods that you'll use as well. So this is the constructor. It's just new promise and you have to give it a function. And the function has got two things that's going to get passed into it. A resolve method and a reject method, okay. So you can do some code here, some amazing talk to the server do something asynch, who cares? But then later on if everything turned out fine, you just resolve, you call resolve with the stuff that it worked, okay. And if it doesn't turn out well, then you go ahead and reject it and you say why you rejected it, okay. And this is, this is how you, this is how you use a promise, okay. And then in your code where you created this promise, you just give this promise back to somebody and that somebody can listen and wait for the events to happen, okay. Alright. So what are some things you could do that's asynch? Can anyone think of any? Like something AJAXy. Maybe something web sockety, maybe you could load an image, you could read/write to local storage, that's synchronous, but it looks ugly when you get everything done. Maybe you could do a lot of DOM writing, you can show some sort of spinner loading, anyway. But this is, this is the simple, you know, A's and B's and C's of the constructor. Any questions on this? No, pretty simple like in success, we're kind of used to this when we do the callback pattern we have this, we usually make you pass in two callback functions, the success callback handler and an error callback handler. So this is like that the resolve is kind of like the success handler, except for I don't have to pass it in to your scope, you just tell me which one should I fire and I can kind of keep the code over in my land if that makes any sense. It's going to actually get a my context, which is really nice. So yeah. And the reject is kind of like the error handler. So anyway. So that's the constructor, let's talk about instances. So now we have an instance, a promise can be in one of four states, so it can be fulfilled, which means it was resolved, it can be rejected, which means it was rejected. It could be pending, which means whatever it's doing before it calls resolve or reject. That's still happening, it hasn't called either of those yet. Maybe it's waiting for a DOM click, I don't know. And then it can be settled, so and settled is more for like terminology only. We just use it so that we can say it's either rejected or resolved, without having to use that many words. So anyway. So let's say someone gives me this promise, I can say promise.then and I can and this then's not going to get executed until, if this thing took 20 seconds, my code would just register this then handler. And it's not going to call this until the resolve method is called. So you just kind of sit there and it just sits there and waits. For those that aren't familiar with promise, this is a pretty cool syntax. So, when you, in then you can pass it a second function, which is kind of like the error handler. So that's the reject handler. So if I made my own get method, like okay so I'm going to go to the I'm going to do this jQuery get and when I get back from the server I'm going to call resolve and pass it the data. But if I fail I'm just going to call reject, right. So this is my, this is my jQuery HTTP method. But I've gone and wrapped it in this new promise. So I return this promise and over in my code sorry I can just say, get users.all and then mycontroller.users is equal to users. And if there's an error I can just say, go ahead and delete mycontroller.users. This is kind of how you would use it, does that make sense? So if the server was super slow, so I call this and then it gives me back the promise and then we register this then handler. If the server was super slow and that took like a minute, which it shouldn't but, you know even a 100 milliseconds can be a long time. This just kind of sits around and it's not going to fire until that thing resolves and rejects, so. That's that. You could also catch it in a second handler, in a second .then. So like if you didn't want to, if you don't like the two functions in the .then. You could put your reject handler in a .catch. That's the other API on the instance. So we could do this, we could say, go ahead and get all the users, go ahead and get all the posts, and then there's this promises.all, which basically says wait until all of these are done and then go ahead and do this. And if any of them fail, go ahead and do this, if that makes any sense. So there's promises.all, which will allow you to wait for multiple things. And then, so yeah, like you could do this too, like let's say the server didn't give you JSON, it gave you a string. So you could say, users.get, users.all or getall, and then you have this string so you could say go ahead and return the JSON parse of that string. And then you could do a second .then and you could say, mycontroller.users = users. So basically when you return something, it's going to pass whatever you returned into the next .then. So see how I did two .thens, whatever I returned gets now passed into the second .then. So you can kind of, when you chain them up you can kind of override what gets passed back. Yeah. Well one question on the chat here. Do the ES6 promises implement the promises A spec or the A+? I think it's A+. Okay. But yeah, so I'm not positive. I know that some of the browser vendors are working on making it be more integrated into the just the elements, but I'm not sure 100%. So, that's a good question. Even more compact, you could just say, get users.all then you could say .then JSON.parse, which it would call JSON.parse and pass it the users. And then you could say, .then and it would actually return it, right, because JSON.parse does an implicit return. Anyway, so yeah, like you could even make it even more compact. A couple of them. So then, so that's the instances of promises, and then you got the static methods, like promise.all is what, remember what we said you'd give it an array of them and it won't fire the .then until all of them have resolved. You've got a promises.race, which is basically saying hey of all of these, don't call the .then until one of them settles. Like just wait for one. You can do say promise.reject and that will just give you a rejected promise. Because like if there, if you're in a certain circumstance, maybe you don't even want to go to the server and do your asynch stuff. And you don't want to just create a promise and reject it for the sack of doing that so you can do, the short code for that is promise.reject. And you can just make a rejected promise and return it. And then the opposite of that is maybe there's one time when you don't want to go to the server and so you can just do promise.
Released7 Apr 2015
How likely are you to recommend Pluralsight to a friend or co-worker?