What do you want to learn?
Leverged
jhuang@tampa.cgsinc.com
Skip to main content
Pluralsight uses cookies.Learn more about your privacy
JS.Next: ES6
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
Description
Transcript
Exercise files
Discussion
Recommended
History of JavaScript
Introduction
(music) So I'm excited to be here, I'm happy that Mark invited me. Of all the people that could come and talk about ES6, I'm like the worst one. Everyone who's involved with it is amazing and I hope that today we can kind of show what they've worked on for the last, you know, three or four years. And kind of understand how their process works and get an idea of where these new features are coming from. As well as kind of get a solid handle on them. So so let's just kind of dive right in. I'm going to do a little about me real quick. So I started in development as a QA person, I was a QA person for years. Any other reformed QA people? No one raised their hand. Oh okay. So I'm also a college dropout, I went to the local community college in Salt Lake and I was studying computer science. And that lasted like, I was going for my Associates and I dropped out after three years, which doesn't make any sense, but I still wasn't done, so. Anyway I started learning JavaScript with, does anyone know have an idea where I started learning JavaScript? Like what technology, any guess, no one? So I started with browser extensions. I just kind of started dorking around on my own time, I was like dude I can change the font size on any site that I want. Or I can delete things I don't like that are, you know, add new features like find out which of my friends is unfriending me on Facebook and stuff like that. Anyway, that was where I started and the second I tried JavaScript I was like, okay I'm in this is, this language is what they should've taught me in school, this language is awesome. So I immediately feel in love with JavaScript. So I'm also a husband and a father, I have two girls and a boy and then there's another boy on the way, so, just crazy full speed ahead with the family. I love ice fishing, any ice fishers, we're in Minnesota so, okay we got one and half hands, three hands, two and half a hands, okay. And I obviously everyone on the front row already knew this, I'm the good looking of the twins, but I have an identical twin, so if you ever see me and I don't say hi it was him, right, it wasn't me, but yeah. I'm also a senior developer at a company called DOMO and I'm on POD, a couple POD cast JS Jabber and Adventures in Angular. And I'm writing a book with O-Reilly on this topic that we're going to talk about today. And because of that I've gotten to, I'm not going to say friends, I've made acquaintances with a couple a handful of the people that are in charge of steering ECMA, ECMAScript which is the language that which is the API that the JavaScript implements, so. And so I'm writing that book, hopefully it's coming out sometime in 2015. I started writing it a few years ago to be honest with you and it's changed so much. Like I'd write a chapter and then they overhaul the feature. And so I got to rewrite the chapter and it was just a lot of work so I kind of stopped. And then talking to Rick Waldron, like the few weeks ago, it sounds like right now might be a good time to get back in, things have kind of finalized for the most part. I also wrote a short book, you can get online for free, it's called JS Next: A Manager's Guide. Just kind of helps you sell your management on why we should alienate, you know, legacy browsers and get the new stuff in. And I'm also an AngularJS GDE, GDE is a Google developer expert, so I was nominated for that. Additionally, did anyone go to NG Conf, any NG Conf people? Okay so. So I also organize NG Comf, which is the first, the biggest Angular conference. We just announced last week the new one coming up on March 5th and 6th, so we're excited. So if someone asks a question, I'm not going to say I don't know, I'm going to say, if I don't know I'm going to say, we'll write it down and I'll answer it after the break. So can we get someone to volunteer to like write down questions if is say can you write it down, my man, okay. So I'll just look at you and say can you write that down, okay. Alright so Rick Waldron again he curated the slides, again I was not present in the meetings with the TC39, so Rick who, he's like the father of Johnny 5, which is a library for using JavaScript to talk to NodeBots. He's also on the TC39, he works at BOcu and he's just an all-around good guy. He curated this stuff, he showed me my errors and he gave me insight, he kind of told me some antics about some of the decisions around the features that were made, so. I just wanted to give a shout out to Rick, he helped out here and he's a good guy. So we're going to talk about these topics today, we're going to talk about the history of JavaScript and kind of the steering committee. And then we're going to talk about new features and then some build tools. And the build tools seems a little bit wild westy still, but we're going to talk about it just to kind of get everyone over the intimidation curve of either the, you know you don't know where to start. So we'll get in and we'll jump into that. So I kind of wanted, I wanted to show off real quick all the features. So this table here is the ES6 compatibility table and it shows you what browsers support ES6 and which ones don't. So you can see on my current browser, which is Chrome, if you look in this column right here, we got a lot of red. So ES6 is still mostly unsupported until you get down to like math and array prototype stuff. But anyway it's still kind of, it's still kind of out there not a ton of solid support, even the support that is there is inconsistent. And if you guys want me to show off these inconsistencies I can, but like between Firefox and Traceur there will be inconsistencies and I'll try and talk a little bit about that. But as you can see there's a lot of features here, too much to talk about in one class. Like some of these features on their own are an hour long class and we don't have an hour to give to every subject. So I picked the ones that I think are the ones you guys need to know. And if we were going to spend a day talking about it, these are the ones I would want to learn. And so that's what we're going to talk about today, but just to kind of give you a comparison, if you click on the ES5 compatibility, like this is how compatible everyone is with ES5. So everyone pretty much does ES5 pretty well. It's not, it's just kind of the ES6 stuff that's still being decided and still kind of in the works. So anyway. So when we talk about it, I'm going to, as I teach about it I'm going to kind of talk about a little bit about where they came from, we'll do some examples, we'll try and walk you through all the different usages of the new stuff. Then I'm going to give you guys some time to use it and then I'll come back and I'll give you some suggestions and then we'll come code those live afterwards. We just, I kind of want everyone to get some time practicing the new syntax. So this is, this slide here is where we're going to spend the rest of our day, we're going to go through these topics.
History of JavaScript
(Music) So we did a JS Jabber POD cast and just a few weeks ago if you didn't listen to it, it was two hours long, it was the longest JS Jabber ever. And Brendon just talked and talked and talked and he, we were like asked him questions, it was like 30 minutes later we could ask him another one, because he just sat there and explained and explained so much and it was awesome. But I'm going to kind of just disseminate somewhat I learned there and then some of the stuff that you can learn through other books and through other peoples talks. So in 1985 Brendon graduates from Illinois and he starts working in the tech field and he eventually winds up a company called SGI, which is Silicon Graphics International and this company, essentially they make the GPU and he's on board with them. And while he was at Illinois and while he was at JS he makes some acquaintance, okay. And then in, around 1994 two of the acquaintances break off and they're like hey let's start our own thing. So Mark and Jim, I can't remember what NCSA, national center for super competing applications. So that's at the University of Illinois where Brendon studied. Anyway, so they're like hey let's go start a company, we'll going to call it Mosaic Communications MCom. And then Mosaic's going to freak about that, right, so they're like hey change your name. So they reran as Netscape, so did anyone use Netscape? Yeah, I kind of miss the Netscape days, I didn't really ever use it, so. Anyway, so in October 13, 1994, Netscape navigator was released. And this is the, this is the home page. Do you guys remember the internet looked like this? This is, this is like how sweet it used to get. This logo is awesome and there's a lot of good stuff. Like they'll teach you how to use the internet to get around just click any blue or purple word phrase. So like this is an example, so I can click that and that, it's like hey you just interneted right. And so, anyway it was super basic back then and this is how Netscape released and this was their sales page. So if you guys, if you guys check out my slides on GitHub, check this page out specifically, it's a gem and I'm happy that the internet kept this around. So six months later they've launched, it's going well, they're like, hey let's talk to our friend Brendon. And let's have him come build schema in the browser. Because we want the browser to have some app like features and maybe who knows, maybe you could even move something around, I don't even know. So they talked to him, he's like yeah I'm on board, in April 1995 they hire him to the wrong team, they hire him to the client or the server team, which he was like, oh well whatever, I'll be on the server team. So he's there for a month because they switch him in May, but he's sitting there and Netscape while he's there that first month, Java's like hey Netscape, put or Sun's like put Java in the browser, put Java in Netscape. So there's like this huge pressure internally to get Java running in the browser. And so Brendon's watching this and he's seeing it and in 1995 he switches over to the client team and he's faced with this Java Netscape thing and he's trying to figure out, is this the way we want to go? And there's a bunch of guys there that they're going through some crazy stuff, go check out the JS Jabber episode. Like they were going to implement their own Java virtual machine just to not have to go through Sun and then they're going to write JavaScript on top of it, anyway. It was about to get crazy and they're like no we're just going to build JavaScript. So he decided, he helped him decide Java's not the language of the web and he's got some reasons why. He says it's too complex. And here's some of things he talked about. He said, you know constantly running Java C, you have to understand the main method on a class and this isn't for a causal or amateur programmer. He decided, like Java is the language for curated programmers and not for the web, which was going to have some more causal and amateur programmers. Which I, you know, none of us should take offense to it right, because it's changed since then. He's like we need something more like VB, but clearly we don't want VB, and he's like I want something that's meant for people who are just learning the program for the very first time. So this was kind of the idea of that they had and consequently this is where the idea of automatic semicolons came from so that it was like super forgiving for these people who forgot and you know we're not going to kill them over a semicolon. So that's kind of where that came from was them trying to be super forgiving. So he starts this project and he talks about 10 tens, like they didn't sit down and be like hey you have 10 days, like on this day you're doing a thing. But he needed to present to his team this alternative to Java before they got roped into doing Java the browser. So does anyone know what this code name project for he worked on over 10 days was, did anyone know? Code name, anybody on the live stream? If you watch JS Jabber you know, anyway. So they call it Mocha, so Mocha was the name of the project. And this was the name that Brendon kind of wanted to stick with long term. So Mocha is, after they built it and they've used internally they go through a beta process and they change its name. Does anyone remember what the first name of JavaScript was? Live script? Yeah, so it was live script. Does anyone know where the name live script came from? Marketing. From marketing, yeah. So Netscape had another project called live wire, so they had a server package called live wire and so they just kind of adopted the live brand. And so they're like live script, live wire, we're just going to do the live one. Anyway so the goal is to call JavaScript at least from the haunches there and so in December of 1995 Sun signs a thing saying, yeah you guys can use the word Java. And like that was a big deal because like there was this guy, his name was like Javansky or something and he owned Javansky.com. And Sun was like, take your website down because it uses the word Java and we've trademarked it. He's like, dude this is like my ancestors had this name hundreds of years ago what do you mean you can't possibly own Javansky or whatever, so anyway. So it was a big deal that Sun was like you can use the name. So that was huge and that's ultimately why they called it JavaScript. And so JavaScript's official in December 1995. So in its first year people kind of started doing some stuff with it, they're like hey let's do some single page stuff, which we like to think of single page apps as being a thing that started in, you know, 2005 with AJAX revolution. But they were doing crazy stuff, they were like hey if I need to get more data I'm going to do this thing where I imbed an iframe with a URL that's specific to what I need. And then it will load data and then I'll pull it out of there up to the parent. So you'll doing all sorts of hacky stuff to kind of get the same type of functionality, right. And they're kind of discovering the quirks of the DOM like if you select everything with the same tag you each get an array no matter how deep they are. And people are kind of discovering that and they're discovering what the good parts are, the stuff that they do and don't like. People are already starting to form opinions. And then there's danger looking though. Anyone have any idea, danger? So in late 1996 Microsoft complains, they're like, because Microsoft's trying to copy this and emulate this, right. But they're like hey Netscape you guys keep changing the API way too much. You guys got to stop it, like you can leave the API solid so that we can be in parity, which isn't the worst complaint ever, right. Except for that it's Microsoft and they do the exact same thing. And so Netscape's like, geez Microsoft's going to like own this thing, Microsoft's going to try and take this over. So let's, we got to figure out a way to keep JavaScript safe so that Microsoft doesn't come in and just kind of pummel it.
EcmaScript
(Music) This is how they do that, they're like let's standardize it. So they have to find a standardization committee that can kind of be an independent party and own the API. And then they can just implement it as JavaScript. So Netscape reaches out to this committee called ECMA and it's independent of Microsoft and it's independent of Netscape too. And so in June of 1997, like they sit down in 1996 and they're like hey let's read the whole thing and we need like x months to approve the whole thing. So they finally get it approved and in June of 1997 the JS, the JavaScript API becomes ECMAScript API, like the interface that other people can implement. And it's the official API for ECMA, the official scripting API for ECMA. And a bunch of people immediately jump on board, people who have interest in the language and in implementing their own scripting language. Jump on board with ECMAScript. Life's good. They're able to roll out some new features, they roll out ES2, they roll out ES3. Everything's going well, they still have a ton of ideas though when they get ES3 out in 1999. And I'm going to, before we keep going I'm going to define what ECMA is. Does anyone know what ECMA script is? Or hold on let me talk before I define ECMA, ECMAScript versus JavaScript. Does anyone not understand the difference between ECMAScript and JavaScript? So I'm going to just go through it real quick. So ECMAScript is a language spec, like they say this object will have this method on it and if you call it you should expect to pass it these parameters and it will return you this type of a return value. So just kind of, it's a specification for a language. And JavaScript is a language that implements that spec. And there's other languages that implement it as well. So ECMA, the docs for ECMAScript, has anyone read them? They're not like humanly digestible very well, they're tough to read unless you have like a solid degree and I don't so they're still really, really hard for me to digest. And the JavaScript docs however will help you write code, like they explain to hey this is how you're going to call it and run it in JavaScript. So there's other implementations of the ECMAScript API though, like action script is based on ECMAScript. And Java's Nashorn is based on ECMA script. And there's other out there, like you guys probably could you know name a whole bunch more. But ECMA it used to stand for the European computer manufacture association. And that's who they went to, they you know, Netscape goes to this European computer manufacture association to get this to be their center scripting API, but later they just reran as ECMA. So it's not, it doesn't mean European computer manufacture association anymore, it just, ECMA is a noun. It's like a name that they call themselves. It's a proper name. So they're role is to facilitate discussions and kind of make sure everyone is participating in keeping it positive. Does anyone, and ECMA puts a committee in charge of steering the ECMAScript API. Does anyone know the name of the committee? Besides him. TC39? TC39, yeah. So TC39, TC stands for technical committee, I don't know what the 39 is, but it's called TC39. So the technical committee 39, and the TC39 is they're the ones currently guiding it today, does anyone have any friends on the TC39? Acquaintances? No, okay. One guy, no one on the chat, alright. So I'm going to go back. So ES3 is 1999 and people, more people started implementing the spec. It's constantly getting implemented and browsers becoming more important in 1999, like remember we're about to have this huge boom that's coming up in 2000 and more people are getting involved in the technical community, in the technical committee. More people are caring about you know the direction of the language. And they get two releases out and then like there's this huge gap, right, like ES3 goes out in 1999, ES4 begins in 2006. So we have this notable gap, right, with not a lot in the middle. So I wanted to kind of talk about what happened there real quick. So IE just kills Netscape, just you know blows them out of the water, does everyone remember that when Internet Explorer was all you used? And in 2003 Netscape ends, they have like one thing they do before they go under though, they're like open-source all of it. So they open-source all of their stuff. And IE kind of gets their glory days and the sandbagging happens and like we have this huge gap where there's not a lot of innovation. The ECMAScript standards body doesn't have any bite to like hey stop doing the things that you're doing and everyone stay like in together because no one's really coming to the meetings anymore. So it's going to take like a Savior to come back and stop this and kind of get things back on track and then, so the browser wars start. And the guys from Netscape start Mozilla. And we get Firefox and I think it wasn't called Firefox, does anyone remember what it was called, I think it was like, was it Phoenix? Something like that, I can't even remember the first name I remember I used it, but I can't remember what it called. Anyway so Mozilla's back, so we have the, Mozilla's new in town and they care a lot about the browser, which is awesome. And in 2006 they're like, they're able to kindle everyone back into talking about ES4 again. So that was kind of the big gap explained there. That was why there was a big, like dead time for JavaScript specifically. And they start talking about ES4, they've got a lot of ideas, a lot of ideas that they left off, like back from 1999 when they did ES3. And some of the ideas conflict and the implementations have different goals, like the different companies involved need different things out of ECMA script that the API. And like Crockford, he's like let's get rid of the bad parts, let's just keep the good parts and Brendon Icks like no let's get Microsoft to work on this generally and make these specs match. And Microsoft's like no we need to add all of this extra stuff for jscript.net and Adobe's like dude we got flash stuff going on, we need to classes and some other stuff that they needed. So there's a lot of pull like in a bunch of different directions, right. So they come up with these two main pushes, they're like hey let's do one small release and then a bunch of people jump into that camp and that's called ES3.1. And then there's another camp that's ES4, which is significantly bigger. So in ES1 we've got Mozilla and we've got Adobe and we've got Opera and we've got other people and on ES4 we've got Microsoft pushing for ES4 and we've got Yahoo pushing for ES4. And there's other in their camp as well. And they spend a lot of time talking about this and they don't do a lot of agreeing and when you listen to them talk about it there's kind of like a falling out where it got really tough and not productive in those TC39 meetings. And ultimately like something's got to give in order for the language to progress. And of this fight though, at the end, they're like okay ES3 wins. The camp that wants to do a much smaller release, they're going to win for now and ES4 can become a thing that we do next. And so these are kind of the ideas of the two camps. ES3 was lighter changes, strict mode, and removed some bad stuff, don't add any new syntax. And this is what some people were fighting for. And then other people wanted some heavier changes, classes, and other stuff like that. And they ended up giving in, the ES4 people just to ES3.1. And which when you look at it a lot of what we're seeing in ES6 is this ES4 stuff that kind of got pushed. And so in 2008 the TC39 meets in Oslo and everyone agrees, hey ES4 we're going to postpone it, ES3.1 that's the new thing, and to represent all of the progress we've made as a committee and as a standardization body, we're going to rave the name though to ES5. And we're going to call it 3.1, we're going to make an official release, we're going to call it ES5, which is why there wasn't an ES4. And that's where ES5 came from. And then we'll move on from there. And Brendon sends out an email the next month and he's like, hey we're working harmoniously now, everything feels like it's going to better anyway. All the other features that ever go into JavaScript are going into a bucket I'm going to call harmony. So a lot of us have heard harmony features, that just means every feature that we want to implement whether it's in the next version for the two versions or the third version from now. It goes into this huge harmony bucket. So in 2008 Brendon kind of admits the idea of the harmony bucket. And 2009 ES5's officially approved, 5.1 is officially approved in June of 2011. And currently, so the ES6 is finalizing right now. And they're still making changes if you can believe it. Like around like modules and around like classes and stuff. So it's still moving, even though they're trying to finalize it, maybe they'll finalize it in June of next year. Browser vendors are currently working on ES6 and the TC39 is, while they're talking about some of these last features for ES6, they're talking about ES7 already and kind of nailing down the proposals for that version.
The Future
(music) I want to talk about some of the goals of the TC39 because they're the ones steering the ship that we're all, you know, we've all decided to be on. So they want JavaScript to be a better language and they've got three, among other goals, three big ones. They want it to be possible to write complex applications with it. And they want it to be a great language for writing libraries in. And they want it to be great for code generators, they want it to be a solid compile to language. Something that you could compile into and do that effectively. They also want a testable specification and you guys will see today they're adopting de facto standards so just whatever industry seems to be doing. If that's a standard everyone's liking, they're going to try and adopt those rather than trail blaze a brand new feature on their own, right. And you guys are going to see, any copy script developers here? So we're going to see a lot of copy script today. A lot of those features and a lot of pythonish type features coming into JavaScript now. So if you go to esdicuss.org/notes you can see all the notes from their meetings that they have once a month. And they do them in different places every time. And then a lot of times like when you're talking about ES6 people are like, dude that's an ES next or JS.next or that's an ES6 or harmony. Like they use these three words interchangeably and they don't mean the same thing. Like they mean different things. So I wanted to kind of talk about what it is that they mean. So in harmony this is like, so we've got the current releases over here, this is like the ES3 features the ES5 features, and the ES5.1 features, like these are already shipped in production and packaged and released, right. And then you've got this whole other bucket and these are all features from the future go here, okay. So this is big bucket where all the future features are at, that's called harmony, okay. And then there's this spot in the bucket which is like a pointer to the next release, okay. And this is called es.next, right. And currently there's a release in that spot and it's ES6. So ES6 is currently sitting in the next seat. But we're about to ship that right? So once that ships ES6 is going to go over to the shipped package, then one of these shipped releases and ES7's going to drop into the es.next spot. So, es.next is a pointer to whatever the next release is that they're currently working on. Harmony is all the stuff, whether it's going to be included or not. Like we've all heard about a harmony feature called object.observe, right. That's not ES6, that's ES7. So like, there are features that are currently under development that aren't ES6. So does anyone have any questions about like those three buckets or anything about like the history that we just talked about? Because that was our history lesson for the day. So I see a question here, it says, can you tell us more about strawman. And so Strawman, I'm going to just pull up the spec real quick. One second. Proposals, okay, so this page right here is the harmony proposal, this is, we talked about harmony being this big bucket, this big idea. So on this proposals list you've kind of got all the features that they want to drop into the language. And some of them we're going to see and some of them have been pushed. Like right here remember we talk about object.observe. So like that's kind down here on the bottom, can everyone see that? Sorry it's kind of small. I'll make it bigger. So we've got object.observe down here on the bottom. And we've got a bunch of other features like let's find, so generators, who's excited for generators, on the survey we sent out a lot of people were like, dude generators. So like generator expressions were supposed to be in, they got pushed. It's still being hashed out. So these Strawman proposals are kind of like, they're just that, they're just kind of like a puppet version of this idea that they want to implement. They don't have any implementation ideas or solidly how it work, but it is an idea of how it should work. So if you guys have any questions about hey what are they strawmanning, what are they currently thinking about doing in the next version? This is a place where you could come to find that out, but also if you go to esdicuss and you go to the notes this notes page would also show you what they're talking about. So they met three days in July if you wanted to see those notes from like the 31st. You can come in here and you can kind of see who's talking what, who's saying what, and you can kind of see who the players are. So we've got Allen Wirfs-Brock, we've got Jeff Morrison, we got Yehuda Katz, Sebastian Markage, so you can kind of see who the players are and who's getting involved on what features. If you want to stay up to date on that stuff. You can also follow esdicuss on Twitter, I think it's Jason Orendorf who runs the Twitter account and he kind of posts, you know, 140 character gems about what they talk about, so. Anyway that's another thing. And if you follow the Twitter handle you'll also be able to see when they post new notes, when the notes get uploaded they'll tweet it out, so. I hope that answered the guy who wants to know about Strawman. So we got a question, how do some proposals move from to ES7 from ES6? So I'll give you the idea and then I'll show you an example. So they've eventually got to ship software, like some of us know, we've been at work where we don't release, we don't release because we're trying to make something perfect and we want to rewrite it and revamp it. But eventually you got to cut a release, right? So ES6 has got to be cut eventually, like if they sit here and rev on classes until everyone agrees, they will never release classes. Because not everyone's going to agree ever on that one specifically. And so when they get to a point where we're not agreeing on it, it gets pushed. And they do that, that's kind of like what everyone has accept. If we can't agree on it it's not going in, and everyone just kind of has to embrace that, and if the whole community doesn't agree with you, you kind of, can't be really emotional that everyone else doesn't defend your point of view like that's just how it is. So let me give you an example. Classes and we'll talk about this later, but if you go down to the very bottom of this class spec I want to blow this up a little bit. You guys see this right here? This is intended as a closed-ended proposal and is not open for major feature additions. So the name of this page is maximally minimal classes, so it's not classes, this is what we could do to get it out. And if you read this it says, future editions of ECMAScript may and probably will extend this definition, however, for the intent of ES6 is only to include the features described in this proposal. Attempting to extend this proposal is likely to result in deadlock that would result in the inclusion of no class definition support in ES6. So eventually if no one can agree on your stuff, you're going to get bumped to the next release. So if you really, really care about it, you've either got to ready to compromise or you've got to ready to push it to the next release. And so that's kind of how things get moved out, so anything that you saw moved out of ES6, something that you really cared about, like array comprehensions. Some people were like array comprehensions, that got pushed because they couldn't agree on it, maybe it was the syntax, maybe some people wanted it more powerful. Maybe some people wanted different syntax around it, but for whatever reason things are getting pushed when the Strawman proposals can't get accepted fast enough. So hopefully that answered everyone questions. Hermantites said, what are the factors, that probably varies per spec, I don't know, okay. He says I answered it, good, yes. Okay so so that was the history of JavaScript, we're good to move on? Yeah. One thing I think somebody mentioned on slide 31 and 34 the groupings were just backwards, you just maybe make a note of that. I think, like Microsoft, Yahoo. Oh did I put them on the wrong side? Yeah, well basically your slide said one thing, but then on your graphic. It was the opposite? Yeah it was the opposite, so is the slide the real? The slides the real thing. Okay, so. Not the graphic. The graphic, yeah okay. Yeah sorry guys, didn't mean to confuse anyone. Hopefully. That's no problem. Okay. I think they saw that. Okay. I just wanted to make sure everyone knew. So I'm going to talk about these features today, these are what we're going to learn some of these I could do an hour and half, two hours on each. We don't have that kind of time today, so on some of them where you guys are like, dude go all the way deep man, do more of that. It's like, I'm not going to do everything about all of it because we don't have enough time. And it's a thing that we could spend a week on if we were seriously like let's talk about all of the intricacies and the nuances of every new feature. It would take us a really, really long time. So I've picked these ones out and this is what we're going to talk about today.
Proper Tail Calls, Declarations, and Rest Parameters
Proper Tail Calls
(Music) Proper Tail Calls, so this is a quote by Dave Herman Does anyone know Dave Herman? Super smart guy, architect no, principle researchers, I think that's better than architect, I don't know, at Mozilla, he's super wicked smart and he's as nice as he is smart. He wrote the, why am I drawing a blank, effective JavaScript, he wrote the book called "Effective JavaScript", which for me is like when someone's like hey I want to learn JavaScript what book should I read, "Effective JavaScript" by Dave Herman. So he says, "Proper tail recursion is a property of the asymptotic space complexity of a language's runtime behavior. That is, in improperly tail recursive languages, control can consume unbounded amounts of space for programs that, when run in properly tail recursive languages only require a constant amount of space." So that's it, you guys got it? So this is how he talks though and it makes perfect sense to Dave, but I read that I got to read it like forty times because I don't even know what he's talking about. So this is what I think Dave meant. In an improperly tail recursive languages, and I'll explain tail recursion in a second, but when your language is implemented improper tail recursion as time goes on the number as the number of recursive calls increases, your memory usage also increases without a bound, it's unbounded, okay. And in a proper, in a language that properly implements tail calls with each number of recursive calls into that function, you're not going to increase your memory usage overtime. Like it will maintain a constant level of memory usage. So that's what Dave's trying to say, so currently we've got this, right. If you try and do, if you try and do recursion in JavaScript, and we'll do an example here in a second just to kind of show how far we can get. This is why it doesn't work, because it doesn't, when it makes the new call it doesn't drop the old stack like it keeps ahold of that, which is going to consume memory. And in a language where recursion was meant to happen, if it doesn't need that old stack, like it if doesn't need anything from up there, it will just drop it and it can go onto the next thing. So here we've got a foo method, it's a recursive method. It's just going to sit here and call itself until it dies essentially then it will, it will return whatever number that it died on, okay. So I'm going to go ahead and run this real quick just so we can kind of see it. So if we go here, can everyone see this okay? So when we run this and it's going to return the number of times it called before it just blew the stack. So we get about 10,416, that's pretty constant. And those are pretty shallow frames, right like, there's not a lot happening frame to frame, they're just saving a value for a number. So, in Firefox this was awesome in Firefox, no dude no, I'm actually going to refresh the page, okay, let's paste this in there. So Firefox actually gets way more, like almost five times more, right. So Firefox is figuring out a way to make the current implementation not suck as bad, but it still kind of sucks. But anyway, so that's how far you're going to get before you die. So if you have a recursive method that you can guarantee that N is less than 10,000, and I use actually lower, I don't have an ie though so I can't run it. But if you can guarantee it's going to run less than 10,000 times then you could possibly use recursion in JavaScript, but you wouldn't. And so this PTC functionality is to get proper tail recursion. So I wanted to explain what it takes to have a proper tail call. So here's a dialog of what's happening for those that aren't grasping it. So when we make the first call it puts one stack in the memory, right. And then when it makes a second call into the method, it's going to put a second stack. And then we got a third one with a new context and those new context take up memory and then by the time you get N deep into here, every single one of them is putting a new stack into memory. Right and it's consuming more memory. So this is why the graph just kind of showed the memory take off up into outer space, because it's taking more memory every single time it makes that call. And it's not releasing those current stacks with like it could do if we had a proper tail recursion, so. ES6 brings proper tail calls. So that's one of the new features. And if you use your tail calls correctly, you'll be able to get that proper tail call functionality and you'll be able to get recursion. So let me explain how you're going to be able to get a proper tail call. And in a proper tail call those previous stacks are going to get GC'd so it's not, GC to reused, so it will release that stuff. So there's some vocab around this, let me explain tail position. So tail position is the last instruction before the return statement, okay. So in this little function right here, in tail position we've got a string. Okay so it's going to eval that string, that's the last instruction before return. So that string is in tail position, okay. And some functions are going to have some functions have multiple tail positions, right have you guys ever seen a function with two return statements? Two return statements? Like if return this, else return that, yeah. Not return return, but like in two different lines of code, yeah. So we understand what tail position is like, it's right before the, it's the last thing that's going to happen before the tail call, before the return statement, okay. But then we have this tail call, so here's two different functions. So PTC stands for proper tail calls, sorry. So here we've got two tail calls or two tail positions we've got our function here again where we've got hello in the tail position. And we've also got a call to get salutation and that's in tail position as well, right. So this is actually a call to another method though. And it doesn't need to hold onto any of the variables up inside this block right here. So that's actually in, that's a tail call and it's proper because it doesn't need, when you make that call to get salutation, it doesn't need to maintain any variables from the current stack. So that's what a proper tail call looks like. But for vocab sake, anything that's in the tail position that's a call to a method, that's a tail call, okay. So when that last instruction is a call to another function, that's a tail call. So we know what tail position and tail calls are. So let's talk about, and we've seen these all over right, like anyone who's done some node, and I don't know why I put script tags on this slide, but anyone who'd done node has seen a results handled like this right. Like if you call the database, you're like hey I'm going to get an error or result set back. And if I have an error, I freak out and pass the error back, otherwise I call the callback with whatever the results were. So we have two tail positions and two tail calls on this thing. And this is common like we've all seen this and we've probably seen worse. So a close call, which isn't, this isn't a tail call even though it looks like a tail call, okay. So what's the last thing that's going to happen before the return statement? It's going to add one to whatever the bar returns, right. So even though bar is like on that line and you're like hey I'm doing recursion the right way, like this is proper, it's still not proper, because it's got to, it has to return back to this stack in order to finish execution. It's in a call bar, but then it has to come back to this stack and add the result of it to one, right. So it needs to maintain this stack still. So that's a closed call, that's not a tail call though. Even though it's trying to disguise itself as a tail call.
Proper Tail Calls: ES5 vs. ES6
(music) I feel bad for even showing you a Fibonacci example, what's that what's that law that if you talk long enough about anything on the Internet it will go back to the Nazis or to Hitler. It's like some law I can't remember the name, anyone in the chat have it? Anyway. There's like a law that the longer you talk about something online, it's eventually going to back to some crazy extreme, like tied to Hitler. And it does, like the longer it goes the likeliness of that happening increases. I think the longer you talk about any language on the planet someone's going to try and make fun of it by saying it can't do Fibonacci correctly right. Like even though none of us and none of the people we know, beside for Godwins law, that's Godwin law is the ties to Hitler, the percentage of the reference to Hitler goes up after time. So thank you Steve W. So yeah and people have definitely criticized JavaScript for not being able to calculate Fibonacci NBD, though right, who cares. So pre ES6, this is what Fibonacci looked like in JavaScript. So you'd have your Fibonacci function and you'd say hey I want the third number in Fibonacci. And it would return a two. And you'd say cool give me the tenth one now and it would say cool 55. And then you'd say, k give me something bigger than that 10,000 limit that we talked about earlier, remember? And it would say, alright dude I know how to do that it's called a range error. Like it knows exactly what to do there. And so yeah. However I will say that this call to Fibonacci was proper tail called because, well it is actually a tail call because it doesn't need anything to calculate. Like it could release a stack if the language let it, but it's not releasing. Anyway, it was written correctly is all I'm trying to say. And now with ES6 the same code so each call adds another stack, each stack needs more memory, and then the memory eventually's going to run out. And you have to wrap this with a tri-catch if you don't want it to kill your execution. So with ES6 though, it'll say yeah I know how to do 3, I still know how to do 10, but I also know how to do Fibonacci to that number. Has anyone calculated that? It's like a lot of bloody numbers, it's a really long number. I don't know how many digits long it was like I did it online though and it was really, really long. So yeah. So this is what it will look like in ES6, so the same code that we had on the previous slide on ES6, it just will work. So if you've got something that wasn't working, I mean you didn't release it but, it would just work in ES6. And if you do have recursion in your code and it was proper recursion like you wrote it to where it could release the stack if it didn't need it. Your code could get faster, like just by grace of the run time being able to handle that stuff better. So proper tail calls only work in strict mode, so if you don't use strict mode you're not going to get it. So that's something you're going to want to turn on. And then optimize your code if you're doing recursion to where it can use this method of releasing the current stack like. If you make a method call, pass it everything it needs so it can release the current stack. And actually this is not the worst idea for every method call that you did, because it's not just recursion that's going to benefit from this kind of stuff. Any method call that doesn't need the prior stack that's running in strict mode would get the benefit of this memory consumption. So if all your methods and that might make your code look ugly if you're passing everything into the method that it needs, like it could kill your code, but I'm just saying like you may want to think about it, right, for the future, anyway, so yeah. So that's PTC, any questions, proper tail calls? We're good, anyone online? Moman any questions online? I think we're all caught up, we're all caught up, okay, cool. Is there any difference like one of my own questions, like if I pass an object with key value pairs and stuff, does it know? No as long as that call that's right before the return, as long as that's a call to another method and inside of that call, like if it's back to itself, it doesn't need any of the variables from the current scope like your passing them into it. It will, like ES6 will enable it to release that current stack and just kind of go on with a new one. So it doesn't matter what you're passing in, you could pass it a function an object, nothing. Yeah? Oh one thing that did come up earlier, I wrote down, with ES6 there's a lot of the features and of copy script and it, so why learn CopyScript, he was asking? Exactly, but you know I say that and it sounds like I'm really mocking CopyScript, but I'm not. Because we're going to see a lot of really cool features today that came from it. So like I'm not trying to say copy script didn't server a point and doesn't still a point like it was like a breeding ground for a lot of really important functionality, okay. Another breeding ground that I didn't actually talk about as I kind of skipped over this was so when there two camps were like, hey we're not going to agree on ES3 or on ES4, we're not going to agree. Mozilla was back at headquarters implementing their features that they wanted, right. So like we hear about, we're going to hear about Let, we're going to hear about Destructuring, we're going to hear a lot of stuff that Firefox has had for over half a decade. Because they just went back to headquarters and implemented it. And honestly that was how they got some of the best feedback, like when they came and implemented ES6, they were like well we've found that blah, right. And the copy script guys could say, well when it comes to arrow functions, fat arrows and skinny arrows, we don't think you should have two, you should just have one. Like, if there's a lot of good feedback they can come from a CopyScript or like a Mozilla trailblazing new functionality without it being part of the standardization body. So that's a good question. I'm not, again I'm not arguing that we should write CopyScript however I am also not mocking people that do and I not saying it didn't serve a purpose. Yeah? There's a question in the chat about ES6 and how would you write a non-PTC Fibonacci? Like would it just work across the board or, I should have written that head of time. It's not going to work across the board like some people when they write it, here I'm just going to pull up a console. They write it so that, like inside the code, you'll be like fib and then like n, plus so like in their code they'll say return fib n and plus fib n -1 or something like that, okay. So that's not, that's not a, the last instruction getting evaluated on that return call is not either of the fib calls. It's the addition of the two results together. So that looks like a, and that's what a call a closed call because you like, oh dude it's in the return spot or it's in the tail spot. It's a call to a method, it's a tail call. This is, this is not a tail call because the last instruction it's going to execute is now add the result of this call, with the result of this call, the addition is the last instruction that's going to happen. So that looks, this looks a tail call, totally not a tail call. And if you roll your Fibonacci like this, it would, you'd still have your 10,000, you know, stack cap and it would die. And probably less because there's significantly more variables in code and there so. Good question. Did anyone else have that question? That was a good question. Any other questions? No, we're good? Okay, so remember how I said I was going to want you guys to try it out, I was like, hey let's, we're going to talk about it and we're going to try to, so if you look at proper tail calls, it's like the saddest, it's like the loneliest number, right. Like nobody is doing it. And like Tracer can't do it, because Tracer's not a, Tracer's not a, Tracer has a lot of these features, but it doesn't have PTC because tracer is like a it complies from ES6 into ES5. So it can't effect the runtime environment, it couldn't make tail calls, it couldn't make the recursion happen, even if it wanted to. And so, but no one else has implemented yet, not even Firefox, Chrome hasn't done it. So yeah it's just kind of a sad, sad little feature. So we're going to keep going. This is the only one that's like that though, everything else you guy will be able to try.
Variable Hoisting
(music) LET, CONST, and block. Has anyone read about these? A little bit, little bit, two guys, online probably the same, okay. So we've got three new types of, two new types of variables and then a new thing called blocks. So CONST and LET replace VAR, right, we're done. Thank you very much, any questions? No, it's actually a lot more technical than that. Douglas Crockford's got a sweet quote. It says, Don't grep-replace var with let or you'll break the internet. Okay? Because they work very differently. And even though let works right, your code depends on var, like it depends on it working the var way. I'm going to call it the var way because it's the not the wrong way, it's just, it's how var works. And if you tried to force your code that works with var to use let, it'd, I'm going to say probably won't work. Just because most people don't understand what var is actually doing, okay. So the topics for let, const, and a block is I'm going to talk about variable hoisting first. A lot of people who are advanced JavaScript people don't necessarily understand variable hoisting. So I'm going to over it so that you can understand, oh now I get what let's doing, because a lot of people who don't understand what var variable hoisting is, don't understand why we need let. So I'm going to go through that. And then we're going to talk about let we're going to talk about consts, and we're going to talk about block functions, okay. And block functions are really cool, you guys will them I promise, even though you may not have heard of them. So variable hoisting. So again, we're going to talk about it because we need to understand why we need to do let, why what's this let deal. And a lot of, there's a lot to understand, like about let. It's not, it's not as simple as, it's the new var, just use it when you want to, because it works differently. And there's some intermittences, your code will actually run different with let than it will with var. That's why I want to explain how var actually works as opposed to how var may work in your head. And some people they think, oh, the way let works, they think that that's how var works. So when I explain let, they're going to be like that's how var works, so what are you talking about. I'm like, dude var does not work like that. So that's why we're going to go through variable hoisting. So this is by a smuck this quote, it says, using let and const instead of var will have the odd side-affect, where your code will execute at runtime just as it appears at development time, okay. And what that means is, var, the way you wrote your code, that's not how it's going to be executed by the compiler. You think it is, but it isn't. And some of us know that and we write out code differently but people who think that your code written with var, that's how the compiler lets it execute, that's not how the compiler likes to execute, the way you wrote it. Another way of saying the same thing, is with var the arrangement of your code has less to do with the way it executes than you think it does. So let me go ahead and explain this. So I want everyone to take a second and grock this function, okay. So we have a call called outer and we're going to call it and it's going to make a variable called A and then it's going to call a function called inner. And all that's going to do is make a variable called B. Does anyone know what's going to happen here? What's going to happen with A and B? They're global, they're going to become global right? Because I didn't use the word var and strict mode by the way if you're running a strict node you'd get an error for doing this. But anyway, by doing this you wrote it like this, okay, this is how you wrote it. Let me show you what the jit compiler evaluated it as. This is how jit evaluated your code. They said, cool you didn't make a var declaration, I'm going to hoist the declaration of A clear to the very, very, very top of the scope, okay, which is global. And I'm going to set it equal to undefined, okay. So that means that right here I could reference A and it would be undefined. And then I'm going to, I'm simply going to assign it down here in these two methods. Like these guys are simply going to assign A and B, does that make sense? So the way I wrote it, not, not, not, not a lot to do with the way that it executed, can we agree, okay. We're going to go into some more examples of this. There's a question in chat, yep. Any idea on why hoisting was invented? That's a good question. I'm not positive, but I remember we talked about where automatic semicolons came from? They were trying to make it like a forgiving language so that if you forgot a semicolon we weren't going to like kill your website because of it. I think it may have come from that, however, I'm not 100% positive. And it may have been a mistake that by the time they realized it was there it was too late to fix. And so like when talking to Brendon Ike, he was like dude yeah we wanted to change some stuff, but we couldn't break the way it currently works. We couldn't have a new version of Firefox come out and then all of the websites don't work anymore. Because variable hoisting, whether you love it or hate it, or whether you don't care at all, the way it works, the internet needs it to work that way still. Otherwise your code breaks, right. And so I don't know if it was intentional, a side-affect, I'm not a 100% positive, but if you tweeted Brendon I'm sure he'd reply pretty quick. Good question though. Okay. So I want you guys to grock this real quick, grock this code right here, like look at it and figure out in your head what it's going to do. So we're going to say foo = 2 and then if true, so this is always going to evaluate right, var bar = 1. So what's this going to do? Is it going to throw an error? Is it going to log a 2 or 3 or an undefined, what's it going to do? Does anyone know? So while you're thinking about this, put on your C hats though, right. Like because a lot of us came from a C base language, right. Where like things worked different than they do in JavaScript, so think about it like that, like you are, like you're a C programmer still. Or a C based language programmer. What is this going to do, like what's going to happen here when I hit, when it consoles, what's it going to log? It's going to say log a 3, yeah, no totally. It's definitely going to log a 3. Okay, right, it's definitely going to log a 3. It's not going to throw an error, because I wrote it this way, but let me show you what the compiler thought I wrote. Well not thought I wrote, let me show you what the compiler did to make sure that it ran right. The compiler said, dude you totally didn't mean to do a var declaration inside this Block, because this Block doesn't actually mean anything. So I'm going to hoist your variable declarations to the top, so anytime you're inside of a global or inside of a function, anytime you use the word var no matter where it is, no matter how deep you are. Your code is going to hoist your variable declaration to the top, when it executes. Not like that it's going to compile it to that and like it's going to, like you could just see it. That's just how it's going to get evaluated, okay. And so this is how our if statement happens, so it's not going to throw an error, because some people are like, it's going to throw an error because the var bar in here it's not going to be reachable outside the sys statement, right. Because we're looking at it with our C hat on. But it hoisted the variable up, so when we get down here bar is totally accessible, it still has the value that was assigned to it and it's going to log a 3, okay. So this is variable hoisting. These are super simple examples, but whether you know it or not, this is what's happening in your code every single day, okay. So some people are like, dude check, move onto the next thing. Others of us are like, what, right. And so, do we have any questions I need to answer on the chat? I don't see any hands in here. Yeah one just came up. So when you declare a variable within a function it only hoisted the top of that function, correct? Yes, so pre ES6 JavaScript is function scoped, okay. So an if block that is not a block at all, that is just code formatting. The syntax on top of what you're doing. And it's execution control, but it has nothing to do with where you're hoisting stops. It's always going to hoist the top of a function, okay. So if you have a function inside of a function, any variables from this nested one, will only hoist to the top of that function. And any functions inside of this, with this function, will hoist the top of it. And the only things that global are the ones where you don't put var on but if you're using strict mode, that's not possible anyway, right. So, yeah. I want to quick mention that this is great to review, but Kyle Simpson will go, he goes like really, really deep into like the compiler and compiler terminology and all the scope and like really deep into this stuff and advanced JavaScript course from the masters. Okay, so just if people want to go like further, if people want to go even further than what I'm, yeah in this specific area that's a good place to do it. Awesome, but it's awesome that we're you know, reviewing it, so. Yeah. Then here's another simple example, what's going to happen here? Oh sorry we have a hand, go ahead. Somebody's asking functions are hoisted before vars, but why? I'm going to talk about that because they're not always hoisted. So let me talk about that. I'll get to that though whoever asked that. So what's going to happen here? What's it going to log? Put your C hat on, is it going to throw an error? I already tricked you I might as well, it's not going to throw an error, what's it going to do? It's going to log undefined, right. Because this is what's going to happen, oh sorry. So what it's going to do is it's going to hoist var name = undefined to the top, it's going to log undefined and then it will assign mark to name down here, okay. So this is how it's going to run. So you go back to my statement I said earlier "With VAR the arrangement of your code has less to do with the way it executes than you think it does," right. So this is what I was talking about. Okay. Alright. So if we run this code, talking about function scoped, and I'm almost done with hoisting I promise. So we have var A out here, we have var A in here, and we log A and then we call run and we do a consulate log of A. This is going to log 2, but this A was actually trapped inside of this function appropriately. So I'm just trying to prove that it is function scoped, like it's not, it doesn't hoist everything up to the top of global, your scoped inside of a function, okay. So function hoisting. Functions hoist 2, which someone alluded to, but not always, okay. There's two ways to make a function. So we're going to talk about them. So you can make a function declaration, which is the top one and the second one is a function expression. Who prefers declarations? Nobody. Who prefers expressions? Okay. So they perform very differently, okay. And let me run through it really quick and it doesn't have a lot to do with let, so I'm not going to spend a lot of time on it. So that same code we had back here, this is what's going to happen. It's going to hoist bar to the top, so instead of var bar = function, it's going to hoist bar to the top. And then it's going to hoist function foo to the top. So it's going to hoist the declaration all the way to the top, but the expressions don't get hoisted. So when people read expressions I can't call bar until the next line of code, right. If I try and call bar before it, what's it going to say? Bar undefined is not a function, right. So I'm going to get an undefined to not a function error. So again that's preference, but that's how a function's hoisted. So if you guys go look at Crockford's JavaScript style guide he says, define all your variables at the top of the function. Just write code like that. So if you ever get into a function and it's like, var something comma something comma something comma something comma something, semicolon. Like they just put all their vars at the top, you know like I don't really like that, why did that guy write like that? He's hoisted it, that person was hoisting their own stuff. Like they were trying to be cryptic, they were trying to make it look like it was going to run. That's all they were trying to do. So yeah hoist your stiff. So that's variable hoisting in a nutshell any questions on variable hoisting? I know I didn't answer everything. Any questions on the chat? How do you use interior slides like you did with a button? O, why? Oh someone's following me? Well no I mean actual question, yeah, that was a question. Oh, I hit O and it goes to the overview and I hit Enter and it comes out as an overview. So these slides I got them from the Google IO slide deck, so. That's why the code works instead of not works, right.
LET
(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 Parameters
(music) Rest parameters, what are they? Has anyone heard of Splat? Splat? Okay copy script developers, okay. Has anyone heard of VARARGS? Have you heard of that? JavaScript developers, not so much? Params, and C+ developers, okay, alright. So does anyone still not know what rest params is, like based off of what I've said? Yep, I've got some confused looks, okay. Let's talk about it, let's show it off then. This is rest parameters right there, okay. So you just prefix one of your parameter names with dot, dot, dot. That's how you create a spread parameter, or a rest parameter. And then the way you use it is like this. So I would have this, this rest param called bar and I'm going to log bar.join, okay. Because what it's going to do is it's going to take all incoming arguments and it's going to put them into an array called bar, okay. And I can do array things to it, like join, right. So I'm going to say I can have two arguments and they will go ahead and put that into a string for me. That makes sense what it's doing? It's just, it's allowing you to catch all of the parameters into an array. So, simple right, it's not too hard I think. It loads them all into an array called bar in this example. And you can use it just like you would any other, any array. And some of you guys are like, oh my gosh I finally, I finally have an object that I can capture all the arguments onto, right. Like I've never had that before. So no one see's these because we've always had that already, right. Like we've already been able to do this essentially, right. Because we've had the arguments object, right. We've always been able to talk to the arguments object. Yeah did you have a? But is this a proper array or is this like the arguments object is an array like object? So I'm going to talk about that, it is a proper array. Okay. Yeah and so I'm going to point out the differences here. So with arguments, arguments is an actual array, okay. It's arrayish, like you poke it and you can see it has a length property so you think that you might be able to call join on it, but it freaks out because it's not an array, it's like a pseudo array almost. And so in order to kind of give the same thing, you'd have to like join it out here or you could always do something that's even more confusing like I'll show you what you could do. You could say, array.prototype.join.call(arguments) and that would do the exact same thing as calling array.join, okay. So you could always do this, you could always pass arguments to the array prototype and it usually could figure out what to do, but not always. But anyway, so yeah that's kind of where I was going was, you can, we always have been able to do this, not a big deal right. It's arrayish, it has a length, and then I get things out of our arguments by index, right, like if it's got three things in it, I get the first one by argument sub0, argument sub1, argument sub2. So I kind treat it like an array in some aspects, but it's totally not an array, right. And so any of the array methods aren't there and if you call them you're going to an error. So we've always been able to have the arguments, but now we kind of have a different way to do it that's, I think, better. And let me explain why. So, oh yeah here's what I was saying earlier, I forgot I had this slide, sorry. But yeah you could call array.prototype.join.call(arguments). And oh yeah you'd have to pass it the space so that it knows what to join on, but anyway. So yeah, so you've always been kind of able to do the same kind of things. There's some major differences though, the rest argument only includes non-specified arguments, okay. So arguments includes every argument regardless of whether you specified it or not, okay. So let me kind of give an example of that. So with this argument function, argumenty, I have name, and if I consult a log name and arguments it's going to go ahead, well actually let's go ahead and run this in Firefox so everyone can kind of see. Can you guys see that, is that big enough? Okay so I'm going to go ahead and run this and we'll look at the outcome. So when this first one was called it logged the name, like we thought it was, but it also logged the arguments and the name was in the arguments. You see that? So I kind of got the name two times, right. Go over here. And then in the second one, where I used the rest parameters, I put the name and then all of the other ones over here. And when I look at it I got the name over here and when you look at this array the names not in the array anymore, only like the last name and the city and state and stuff. So you don't, it just picks up the rest of the stuff, not everything like the arguments object. So that's one of the, that's one of the major differences.
Rest Argument Rules
(music) So there's some rules, you can only have one rest parameter per function. Okay. Can't have more than one. It's got to be the last parameter, okay. It can't be the first one and I'll show you guys why. And you can't use arguments anymore if you're going to use it, okay. When a function eval, it's going to say, do you have a rest, cool then I'm going to freak out if you use the word arguments. Unless you make a new variable called arguments, then it's okay. Is that confusing? A little bit. Anyway, don't ever make a variable called arguments, if you do call me and I'll come punch you in the neck. Anyway, yeah. Don't make a variable called arguments, right, it's not cool. Okay, and you can't use default values on a rest parameter and I'll show you guys the default values in a different slide deck that we'll do later on, but you can't use default values with a rest parameter. So let's take a look at each of these rules, they're all, they all have some intricacies I want, I kind of want to point them out. So you can only have one rest parameter per function. So I want you guys to look at this code and try and pretend that you're a V8 or your spider monkey, okay. You are C++ now, okay. And you see that someone said, okay they want two rest params and they're passing me all this stuff. So it's like, I don't know what things go in first and what things go in second, I don't know what you expected me to do here, right. So it's going to, it's going to die if you try and use more than one, okay. So I think that, that when I read that I was like no that makes perfect sense, like you couldn't do more than two, or more than one, because it wouldn't know what to do and what, so. So yeah you'll get an error that you've used multiple rest parameters. Questions on that one? No pretty straightforward right? Okay it has to be the last one, so that one I think makes good sense too. At first I was like, well like consider this example here, 1234, right I'm going to pass it in. Like which one should, which one should go into bar and which one should go into biz, like I don't know. If I call form should I just read from the end, should I like read backwards? And like just put the very last one in biz and then put these three in bar? But what if I do this, which one should that go into, like I don't know what to do, like so? It's got to be the last one and clearly for like sanity and code readability purposes, okay. It's this is your last parameter, it's not your first, it's not the middle one, in fact if you try and do this you're going to get an error, okay. Alright any questions on that? No? Okay. So if you've got a rest parameter like this and you try and talk to arguments, like I already said, it's going to give you a syntax error, because it actually doesn't provide the arguments object anymore when you've used a rest parameter. So that's why you're going get an error saying that variable hasn't even been declined or declared. Yeah? Can, you can't get to like caller, you know, any of the, those aren't part of the spec I guess. There's like you know arguments.caller to get the function that called. Do me a favor, try it in the time that we have to practice this stuff out and let me know, is that cool? Okay. So yeah, so like if I call do something 123 and I try and access arguments in there, you're dead. Questions on that one? Simple. No default values, so default values is, this is a new syntax we haven't talked about yet, but like if I wanted to say if the params is empty you make it this array. Like I couldn't do that. There's no such thing as default values with this rest parameter. Okay. So you'll get a syntax error on that one. Any questions on that one? No. Okay that's rest parameters. That's a new functionality, you guys excited about that one? I'm stoked about that one. Okay. So try this out. Try it out on Firefox, try it out on the Traceur repl, you know try and make bug around with that arguments object, see if you can get the, see if you can get the caller and the callee stuff like what he was saying. Just test getting those errors so you know what to expect so you don't freak out when you get them, like in the wild. Like don't use two of them, make sure they're the last one. Try and get the errors to though, like test the boundaries and make sure that it is failing where it should fail. And just so you can kind of get comfortable with how it works. So try that out, let's come back in 10 minutes, yeah? Are there are any questions? Yeah, before I ask it actually are you going to talk about some of the new array features later at all? No. Okay, so I mentioned in the chat using array from on arguments to convert it into an array, but that's also ES6. And one of the follow up questions was why would we need array from if we already have rest parameters? And in my mind it's just because it works on other array like things, right, it doesn't have to be argument specifically. Yeah, I don't know? That's a good question. Does array from, could you pass a set to array from? Anything that qualifies as that array like, you know, where it has, where you can iterate it, basically. Yeah. That's a good question, I don't know. I'm not sure about sets. Yeah. Yeah you could try that out right now. I don't know. I mean every, Firefox and Chrome all have the new syntax, so were there any other questions I didn't answer? I think we're caught up. Okay. I'll ask. Alright. So see that, see what is right in there. Like they figure out a better way to do LET. Let me show, I'm going to show you what they tried to do. Like and even this version of LET will never, even when it compiles into it, it'll never respect the temporal dead zone. Like you'll always be like, how come I can still reference it before it was declared? Like even if you transpile with Traceur you will never be able to implement, like as along at least with this version of solid implementation. Let, what it used to do for LET was this, does anyone know how you can get a temporarily scoped variable mid-block in current JavaScript? Because there's a way and I actually, I found it on here, it melted my brain when I even thought about it. You going to have to use like defined property. Let me show you, dude it was crazy. They would do this, this is not a joke. This is what they would do, okay. I'm just going to rewrite these three lines. (working) Guess what we have right there? We have a temporarily scoped variable named e. (working) That's how they use to compile LET. They were like anytime you used it they would throw, just to get this exception parameter they could then reassign to whatever variable value you said. I've heard that's also the way that Traceur, at the moment, is emulating LET in the. No this is how they're emulating right here. Okay, no but in the browser, okay. Yeah, yeah they used to. Yeah. Totally, like that's actually how I found it, that's why when that guy, when I saw him use it this way, I was like huh, that's interesting because it will never, it will never be able to properly like function with a temporal dead zone idea. But I'm guessing it's way more maintainable and I'm guessing it's more performant, because I can't imagine it's very performant to say, stop execution and now throw. Like I got to imagine that's pretty costly. So if it was trying to throw every so often I can't imagine that that was like a good thing to do, like on a large scale, so. So this is probably more performant, it's for me definitely more readable, not that I would ever try and read this code anyway, but yeah. Like if you use a grunt tracer, like I said, and for those on the live stream, using a grunt tracer you can give it, you can tell it to provide you with source maps. And then in the browser if you get an error you can click on it and it will take you back to the original source, so. So yeah. Did anyone have anything they found that was weird? All kind of what you expected, kind of normalish? Yeah. Someone had Firefox 8 on there, that was kind of weird. I'm guessing we got that figured out though.
Spread Operator, Destructuring, and Arrow Functions
Spread Operator
(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.
Destructuring
(Music) So destructuring allows you to bind a set of variables to a corresponding set of values anywhere that you can normally bind a value to a single variable. Awesome right. We're like what does that even mean. Okay, so normally we build stuff and when we take things apart, when we destruct an object it's always been manual. Destructuring adds a lot of, well not a lot of, it adds some new syntax and some new paradigms into JavaScript, things that we haven't seen before. And we're going to talk about those, we're going to talk about the pattern matching, the pattern matching, you know the more we get into it the more advanced it can be and it changed earlier this year and I think it's solid again. However it is, it could change again, but for now. And you guys are like what is pattern matching even mean? But I'll show you, so. But some of this stuff, I mean, I don't think it's going to change, but it could. So there's really two approaches, like there's two main things you're trying to destructor, when we pull an object apart what are we trying to pull apart? We're trying to pull apart bits of JSON right, and we're trying to pull apart arrays. Really when we take something out we're like, give me that piece of that array or give me, give me this value by this key into an object and we try and pull them apart. And so I'm going to talk about those separately, not in the same section of slides because they are different and when we talk about patterns the patterns change. And the concepts are similar, but the stuff's going to change. So we're going to talk about them separately. Destruction in objects and then we'll talk about destruction in arrays second. So here's kind of your first view at destructuring. So imagine I had like this object that had a city, state, and a zip in it and I, I called getAddress to get it, okay. And I want to pull, I want to pull the city and the state and the zip out. So this is the syntax you're going to use to pull it out with destructuring, okay. And with just one line of code I've got three new variables that all went into the return that value of that getAddress call, to say hey I'm equal to the city property of that object. State says I'm equal to the state property of that object, and zip said, I'm equal to the zip of that object. Does that make sense what's going on there? And then you can kind of log them separately. So normally we spend like towards the top of our functions, we spend a lot of time like making sure something's got a default value and pulling things out. And we spend a lot of time at the top of each of our functions, kind of data proofing the function that and kind of setting up the code that's going to run below. And destruction helps us get that done quicker, okay. So it helps us pull incoming objects apart, sorry. Okay. So you could, yeah. Okay so one thing to notice is that we have braces on the left side of an assignment expression now. Like we've never really seen that before. Before the braces have only ever existed on the right side of an assignment expression, so whenever we've seen an equal sign, it's not been on the left unless we are comparing an object on the left to something like, that's a comparative that's not an equals, right. So when we're assigning something we've never, we've never been able to have a curly brace on the left side of that. So that's a new thing that kind of when you look at this that might be kind of what grabs you first. And we were able to make three sub-variables just by comma separating them, okay. And this over here, this is called the destructuring pattern, okay. So I had a call those things very specific names, like I knew in an address there was a city property so I called my variable city as well. Otherwise this wouldn't have worked. Like if I tried to get foo out of it, there's probably not a foo in the address a foo property so it will work. If I wanted to alias them though, like let's say I wanted to pull city out and I want to call it C. This is kind of the pattern that you would use and if I want to pull state out and I want to call it S and zip and call it Z, this is, this is the syntax that you would do that with. So you can kind of alias some names. So if we wanted to dork around with this. (working) Oh yeah, yeah, yeah, yeah, yeah. (working) Okay. So I'm going to turn this off, show generated code, okay. So this is kind of how you would use it, like when I log the city, state, and zip the C, S, and the Z, this is what I get. If I try and log city, state, and zip it's not going to have them anymore. I could go ahead, it freaks out and actually throws a compiler, it says I can't find city and it will do the same thing for state or zip. So this is kind of destructuring on the fly. So this is, this is kind of how you alias the names of the things that you're pulling out. So this becomes the name of the property inside the address and then you want to alias it to whatever you want to alias it to, that's how you do it.
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.
Destructuring Pattern
(Music) I'm going to explain the patterns real quick because you guys have been seeing this pattern and I've been vague about what is it doing, it's not, it's not as simple as it looks, okay. I know this looks like just some simple syntax and I'm saying, find the name and find the age and then pull them out, like. That's what it looks like, it's actually a little bit more complicated. Whenever you see a brace on the left, if I see a brace on the left it means the thing on the right had better be an object or I'm going to get an error, okay. So yeah, like anytime you try and use this pattern, if it's not an object, we're in trouble, okay. And I'll show you how you can get into that. And the object on the right must have those properties that we're saying. Like it's got to have, like if I say destructor a name and age out of thing it better have a name and an age, otherwise we're going to get an error, okay. And this is called an irrefutable pattern. Does anyone know what, can anyone say what irrefutable means? Like in court if someone gives an irrefutable testimony, that means. It can't be refuted? Yes it's the opposite of being able to refute. Like I, it's not, it's completely qualified, like you can't argue with it at all, it is what it is, it's irrefutable, okay. And this pattern, when we write it like this is irrefutable. So if we write like this and I say, name, it's got to be there or we're going to get an error, okay. And that's not very forgiving and everyone in this room like's dude Java's way more, your JavaScript's way more forgiving than that. Why is it not being forgiving on this? So let me show you a little bit. So here's an example of where it would freak, okay. So if I tried to pull an address out of this person and we can clearly see on line one there's no address. We're going to get an error on this one, okay. So it's going to throw. It's going to say, some sort of I wasn't able to find this property that you're looking for. The pattern didn't match, not a good pattern, I'm not sure where it will end officially, but you're going to get an error on that line of code, okay. So how do we get passed this now? Like we need some sort of forgivable pattern right. And so they implemented, and this is what changed majorly, like earlier this year. It was set in stone and it maybe was, it was towards the end of last year. Like it was solid, the structuring was done. And then they busted out this pattern stuff and I think it made it better, but let me explain it to you guys so that we can kind of like rest assured knowing everything's good. So if I do that, you see what I did there? See what's going on there? I've got a question mark before the address, we're good again, okay. Question mark means maybe, possibly, not 100%, like try though. If it is good, if it's not undefined, undefined is good, okay. So this is what you're going to do. Everyone is like, okay I'm going to go try this on the Traceur repl, oh it doesn't work, yeah it doesn't work yet on the Traceur repls, so just stay with me because it doesn't work yet. And I don't think it works in Firefox either, so. It forgives address for missing, what about age or name though, like what if they're missing? Those like, what are we going to do on those ones? So are we going to like copy, are we going to give everyone their own refutable property and say this actually doesn't even have to be a person. Like you could pass me a book and it doesn't even have an age, a name, or an address. Like it's just a thing with a page number and that's it. So we could refute, we could make every single thing refutable or you could make the whole pattern irrefutable, yeah, or refutable, sorry. Yeah? Somebody's just kind of saying why is the question mark before the variable name, why not after and then does it also work in function signatures? Yeah. The same question is yes, the first question why. (talking) Yeah I mean I think you're, I might not be the best guy to ask that question, because I wasn't in the meetings. But I mean I'm sure that, I'm sure someone at one point said that, I mean I'm sure that whoever asked this question wasn't the first person. Like someone asked that question before, like it was decided that it would be first for a reason. Operator is also before, is it before your copyscript? Maybe that's where they got it then. Is the existential operator a question mark? Yeah. Okay. Maybe that's where they pulled it from then. That's good to know, thanks for sharing that. Any other questions? Yeah. What happens if like so name isn't found, it does an error, what, if you use name later is it undefined? So defined, yeah, yeah, yeah, yeah, definitely. So there's two kinds of undefined, right? Well depends on who you talk to, like, you try and use the word undeclared and people are, oh there's no such thing, no I mean there is. Like if I try and reference a variable that's never even been mentioned whether below or above, that actually is like a runtime error, right. But if I try and reference something that's just not defined, like it doesn't have a value that is declared, but doesn't have a value. That's just undefined, right. And that may not throw an error, whereas an undeclared definitely throws an error right. These will be treated as undeclared, or undefined they won't be treated as undeclared. If you're using the refutability, if you're using irrefutable, it's like it's undeclared. (Question) Comes after, well I don't know why, I'm sure that Douglas Crockford tried to get it after then. He did a lot of things to try and, you know, emulate a lot, just like Copyscript would. It was awesome, I mean everyone's opinions were shared and this is where it ended, so. This is what it is and because you can't break the internet, I don't think it's going to change.
Patterns In-depth
(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.
Destructuring Arrays
(Music) We're going to move onto destructuring arrays now. So here's a basic example, okay. Pretty simple though, like we got an array 1 to 10 I want a variable called first, second, and tenth. And I'm just going to pull them out of this array, nums, okay. And then I can log them and they're the right values. So if you want to skip one you just leave an empty comma in there. Again new syntax you'll notice we got curly braces on the left hand side of an assignment expression. That's happened before, but not in this way. So like before, before you could be like array subzero equals one, so you've had curly braces before, but not like this, right, like not in the destructuring pattern. And so there is kind of some new syntax to this and I think it's all fairly simple to grock. Do you guys think it's simple? Right. So. There's not, sorry, with a comma is the three the way to do it or is there a more esthetically pleasing. What you think my codes ugly, what? Huh? Do you think my code's ugly? Yeah. Yeah no, no, no, no this is how it works, this is how it is. Okay. Yeah, yeah, yeah. And you also really have to count. Yeah I mean if you knew there was 10 things and you knew you wanted the 10th one, and you didn't care about the middle ones, then yeah that's what you'd do. So does that look better than saying, 10th equals array sub 9? Probably not, but who knows you know, I don't know. You guys will know. And there's no way to map, like with the object destructuring, you couldn't do like index to variable name or anything? Like zero to first, one to second? I don't know, but I hope so. I don't think so though. Is there a way to find out the last, I mean that's already mapping right? No. I mean, so I've kind of thrown this concept and patterns out to you guys and it's not like regular expression. Like where it can kind of do a ton of things. Like you kind of need to know what you're looking for and when you're using these patterns it's not like, it's not, it's not like give me any random thing. Like in JavaScript we don't just, we don't just pass random objects into functions. Like the function coming in, you kind of know what it is, right. Like I know this is a user thing and it's going to have an ID and the name and stuff like. So you kind of know what's coming in and if you don't, then like the patterns isn't going to solve your question, you need to something else. Maybe template strings with their DSL function might do it, but we're not going to cover that today. Okay. So no, no I hope so, someone said can I destructor 10th, the 10th thing to a different name? I mean I am kind of doing that already like I'm pulling the array subzero out and putting it into a variable name first. So I am kind of like naming them as I pull them out. So that's already happening. Yeah? You just chose first, second, and tenth to make it easier which position it is in. Yeah, yeah, yeah, yeah, yeah, you don't actually, I mean though the word first doesn't mean anything it's arbitrary, right, I could be foo or bar. I just did first, second, and tenth just so you guys would know this is the first one, the second one, and the tenth one, just like so the example might make idiomatically a little bit more sense as you look at it. So. Good? Okay. Okay so some things you can do. In the past like if we swap variables so you know given that I've got these two variables, a is 1, b is 2. In the past I need a temporal or I need a temp variable to go ahead and swap these things, right? That's how we would do it normally, right. So temp becomes a, a becomes b, b becomes temp, and then temp we don't care about anymore, we kind of throw it away. Not that we do this a lot besides homework assignments and school, but I mean if you needed to for work for whatever reason you could. This is the new way. You put a and b in an array and then you pull a out and assign it to the b property and you pull b out and assign it to the a property. Does that make sense what's going on there? So that's like one way, I mean that's one thing. I don't know if this is as practical as it is looks cool for a demo, but it is a thing you could do. So and again, you can couple this up inside the method signature. So if I have a function called do something and I'm going to pass it an array of numbers, I could destructor first and second and then everything else can go into the other's guy. That's pretty sweet right? So you can just throw it all up in the method signature just again you're, one thing that I love and I love in ES6 and I don't like about now, we spend the first lines like pulling things apart and like setting up the code for the rest of the method. And this kind of stuff helps you get it all up in the method signature. Someone just OMG'd on the stream, that's awesome. So here's nested. So if I have this nested array. Again the variable is 1, 3, and 6 are arbitrary, I'm only using them so you can see what variable I'm meaning to get. So I have a three dimensional array right here, 1, 2, and then this big, or this array right here. And then I have another three dimensional array with 3, 4, and then the third bit is 5, 6. So I want to pull out 1, skip 2, I want to pull out the 3 into a variable called 3, skip 4, skip 5, and grab 6. Does that make sense? So and you could do that all on a method signature, so. Pretty exciting. No one else is freaking out on the live stream, so that's good. Pattern errors, so like the first one, line 1 there, you could pull x out and you know it's basically going to throw the 3 away, it's only going to pull out the index subzero and assign it to variable x. So x would equal 2 after this first line. On this second one it's actually going to pull the 4 out, because arrays and objects they're indexes are actually strings, right. So when I come to this array right here, and I've got something in the zero spot, it's going to go look for that object subzero, which is it going to find it? Yeah because someone made a property called zero, which is a really smart thing to do in a map, right. Anyway it would find it and it would assign that to 4, so. Would this work? Unfortunately that would work, yeah, so. And then if you tried to pull x, y, and z out of, I you try and pull three out and the array's only got two, you're going to throw an error. Does that make sense? Is that what you thought would happen after what we talked about earlier? If you try and pull out z and it's not there, we all kind of was like, it's not going to be very forgiving unless I throw a question mark, right. Okay so here's some refutable stuff. So that first line is the same exact thing we just looked at, where it was going to throw an error. But we just refuted the whole entire pattern and now we're fine. So x is 1, y is 2, and z is undefined, which is hopefully what you guys thought it was going to do after you expert explanation of patterns. And then the second line is the same thing except for instead of refuting all of it, you're just refuting the third variable.
Questions
(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
(Music) This function comes from a lot of languages have these things now they're called lambdas, right. In JavaScript like the idea of lambda doesn't make a lot of sense, I mean not that it doesn't make sense, but another language is more significant because like you have to tie functions to a methods to like objects and it's just like a random objectless function that doesn't make a lot of sense, but we have that now. And for us it's just a different syntax for functions than, we've always kind of had this, but it does have some different performance stuff that you may not be used to. Like the way your code used to run, is not the way it's going to run if you use these arrow functions. So I'm going to go through that and I'm going to explain it to you how will my code be running different, like I just replace all my functions with lambdas, not only will it kind of break, it's going to totally break. Like big time, major. And I'll explain why. So yeah. So arrow functions, that terminology comes from Copyscript again and Copyscript has two versions of the same thing, okay. So Copyscript, and I'm going to explain it because it has some relevance in what we're going to do, okay. So Copyscript has a fat arrow function and a skinny arrow function, okay. So they have two flavors of arrow functions. JavaScript only took the fat arrow function, okay. And if anyone knows JavaScript, or Copyscript and you understand the difference between the fat arrow functions and the skinny arrow functions, then you already know what I'm about to teach you, okay. Because our, this arrow function in JavaScript does the exact same thing, which it didn't know in regular functions don't. So precedence, you've got lambdas and the fat arrow function from Copyscript. Again we're taking these de facto standards from other languages and ES6 is going to throw the word fat off of the front and just call it arrow functions. They didn't need to call it fat arrow because we don't have two of them, so we don't have to specify the difference. And there was talk about bringing over the other one too, but they were like, we can already do it that way, let's not bring over both, it's too much of a learning curve for new people. Let's just keep one. And if you guys go through like the logs you'll read why it ended up this way, so. So these two functions are a lot alike, okay. And if you execute them they'll execute for this example they'll execute the exact same, okay. So like one of the main differences you'll notice is we had to use the word function for our first example. So we're not using the word function, okay. And so that will help with minification, that's kind of nice, right. So we'll get performance enhancements at least there by using these. We're still using parentheses for the parameters, so we don't have any parameters, so like up here we have these parameters, these parentheses with nothing in them. Over here empty parentheses, so. And then we just kind of do this fat arrow we kind of point at the function body and we just put a 2. And it's going to implicitly return that. Whereas in the top function if we wanted it to return it, we had to say go ahead and return this, okay. So you can, you could wrap the body of this arrow function, you could wrap it in parentheses, or in braces if you want to. Like if you want to put squiggly braces around it, do it. It's going to not, it's going to stop implicitly returning though. It only implicitly returns if you don't wrap the body, okay. So if you, the second you put parentheses up there, you're going to lose that implicit return, so you're going to have to type the word return. So that, that might be confusing. Parens for parameters, no single brace for the single line arrow function body. So you can do multiple line and arrow function bodies and on multiple lines you are going to need to wrap it with braces, but if you're just doing like one line, I'm thinking like D3 you know and like D3 there's a lot of like .data and then a function and .this and a function. And then you just do like one thing in the line, like you could do a lot of this stuff and that kind of stuff. So on the single line arrow functions with no braces, it does implicitly return like we said. So I kind of want to, I want to talk about the parentheses around the parameters rules. And some of you guys are going to love this, I can already tell. But shout it out if you absolutely love it, shout it out. Okay so if you have no parameters you have to use parentheses. So if you don't have any parameters, you must use parentheses. If you have one parameter and one only is optional, you can either use parentheses or not, okay. Everything else, well I'm not talking about everything else, I'm just talking about the parentheses, the parameters, okay. And then two or more you have to have parentheses around them. So basically another way to sum this up is with only one parameter it's optional parentheses, okay. So I wish they wouldn't have done that, I wish they would have just said hey it's always parentheses, there's no not parentheses, it's always parentheses, do it that way, anyway, so. That's the other way to sum this up is when you only have one parameter you don't have to put the parentheses in. Because you're probably going to come in here one day and refactor it and like do comma other thing and you're going to like get an error because you forgot to put the parentheses around. I'll probably always use them just because I don't like to deal with those kind of problems. And I'm sure like uglify will go through and be like, hey do you only have one cool I'm going to freakin remove the stuff out then. Like you know what I'm saying, I'm sure you'll have our build tools will take care of stripping off that extra parentheses if we don't need them. You know what I'm saying? And if you have a function that's only one line and you have a return statement, I'm sure that the uglifiers will be like, dude get rid of the return, take the braces off, and just make it one line like so. We'll get some stuff, we'll get some tooling around it and we'll make this stuff easier, but yeah I'm not sure, so. Anyway So let's talk about the body declaration. So again I kind of talked about this. So here we have a function, it takes a number, and then it returns the number times itself, right. And this is, if you want to wrap the body with braces, you can but you've got to then give it a return statement. So that's going to get confusing to I think, some people will run into some bugs where they take a one line method and make it two and they forget to add the return value on the second line. You know what I'm saying? Like the return instruction and I think they'll be like, why isn't this working? So anyway, just keep that in mind.
Arrow Function Examples
(Music) And some places where you could use them, like if you wanted to like make a map out something, currently we do something like this. We are like come on, like (working) Oh sorry we're doing map, right? So currently this is what that would look like. Everything kind of squares up and it returns it to you. So this is, this is what that would look like in, with an arrow function. It would be one line, less code, if you ever have the need to make a map of squared numbers you could do that. But you could, I mean, a lot of times when we do, when we call a map function, we're just returning like some ID, so instead like you could pass in an array of like user objects and just say, return user.id and you'd have a map of user objects, anyway. Just a thought, this is somewhere where you could use it. You could have a key maker where you pass in a value and it says the key is this value, I don't know. And then you could make 100 keys or you can make a key with the value of 100. But let's talk about the real benefits of these arrow functions and I say benefits and it will also be the kind of the source of some confusion. So let's talk about it. The way that this, who like, 1 to 10, who really understands this in JavaScript? Who's like a 3? Who's like a 6 or 5 to 6? Who's like a 7 or 8? Who's like a 7 or 8? Who's like a 9 or a 10? I'm going to raise my hand, I think I get it, but I don't know maybe I'm a 7. Okay if I was going to interview I'm a 10, but like if I'm in front of my peers it's probably like a 8 or 9, anyway, okay. Okay I want you to look at this function, let's talk about what it's doing, okay. So we have a widget object, true? Everyone agree, okay? And we're going to call it widget.init, right. And widget.init is going to say, cool onto the document let's add a click listener. And we're going to say, I want you to call this.do something and pass it the event type. Because the click handler has an event, right. So does anyone know why this is going to, why that line's going to error? Because d something is scoped to the anonymous function or this is scoped to the anonymous function so a do something is scoped to the. In the context that this exists, what is this? Is it the document? So are you sure it's not like the DOM element? It might be the DOM element. I was at a 5. None of us really know? Now I'm at a 3. We just all went down a little. Yeah it's not the widget though is what I'm trying to say. So when you say this.do something you think you're saying widget.do something, you're not saying that. That's not what you're saying. You're actually saying window.do something, okay. And window doesn't have a do something method. So what's going to happen when you try and it's going to say, window.do something is undefined and I want to invoke undefined. What's going to happen when you try and invoke undefined? Undefined is not a function, right, okay. Okay, that's exactly what's going to happen. So there's two ways normally people correct this, do you guys, can anyone shout them out for me. Self is this. So who said mind, and then the other way this, var yeah var something equals this and then instead of, here I'll pull it up. So here's the two ways you can do it. Your function handler for your event, you can say go ahead and bind it to this and when this line of code is running, this is actually the widget, okay. So you combined that function to this or you can say var me or var self or var _this equals this. And then instead of calling this .do something you call me .do something or whatever you use, right. Who uses self? No one. Who uses bind? Yeah I use me, so. Anyway. This is how you fix it today, right. Like and when I used to write, I used to write in Sencha, is that okay? Anyway I did and it was cool, but I had to do this a lot, it was a lot that we had to do this kind of stuff. And so fat arrow, or arrow functions, sorry I'm going to keep calling it fat arrow and I don't mean to, anyway. Arrow functions aimed to solve this problem that we're dealing with right there. This is what arrow functions is for, okay. Okay so this is how you would rewrite that exact same function with an arrow function. So you know it's basically the same syntax, but instead over here you just have one of those anonymous functions. And I've wrapped it with braces so it's not going to return. It's just going to call this .do something, but in this context when you use an arrow function at the time that this line of code of evaluated, this was widget, right. So it's actually going to go ahead and bind this event call to this, right. So instead of our frameworks, like our backbones and stuff, people are going to start using this syntax because it is nice. It's nice to not have to worry about that stuff or to have to like go through and bind all your functions or alias this onto something else, so. So in Copyscript you end up actually almost always using the fat arrow rather than the normal arrow? You think that we'll be sending JavaScript as well? I'm going to show an example of why won't. So like in this, like because in this example think about it, when this widget is being created and I'm going to, can I answer that in another slide? Okay good, I don't want to ruin my slide. I want to ruin my own wave dude. Does anyone have any comments or questions about that, like that makes pretty good sense what's going on here, right? When that line of code gets added as an event listener, this is the widget and so it knows exactly what to do. So in that way the code, I mean it will at least run like we think it's going to run. Whereas with, sorry, with a regular anonymous function it doesn't run like we think it's going to run. Okay, so I want to talk a little bit more about these functions, so the type of arrow function is function, okay. So actually Rick Waldron corrected me on this, it does have a prototype and it is function, but there's something about function it doesn't have. Sorry I can't remember, he corrected me on this and I didn't put it into the slide. Kind of nullifying itself, now that I think about it. Anyway, so if you call get prototype on an arrow function it's going to call, it's going to return the function prototype. So here's a big difference though. Like so if I have a function foo and a function bar and the one is a regular function and the other one is an arrow function. I can use the regular function as a class constructor, I can say new foo. And if I try and do new bar it's not going to work. You can't make classes out of arrow functions. Because they're binding. Is basically what it is, yeah. Because of how it's going to bind this. If it bound this on an arrow function, what would this always be 100% of the time, the window. So it would be tough. So you can't, I mean it wouldn't really be useable, so. And I guess they can make an exception in the case of the word new, but I don't know. So the rule is you can't use this as a constructor, we're cool? Alright. So someone, you asked about this earlier, you were like hey man why don't I just, hold on. I can't remember what I was trying to teach you guys with this slide. Oh yeah, yeah, got it. We good? I got it, I got it. Okay, so I have I have a widget here, right, it's got an ID of 123, and it's got a log method, okay. And when I call log it's just going to say, it's just going to log this.id. Simple? Everyone understand what's going on here? So if I say new widget, new widget.log it's going to just log widget log and a 123. Simple. Does anyone not get that, we should all get that. Okay we got it. Alright so now I'm going to say new widget.log.call and I'm going to pass it a different this. When you call, when you do on a method, when you do a .call, the very first parameter is a new this, you're basically reassigning the this. So I'm trying to say, instead of treating the widget as this, treat this pseudo widget as this. So it should call log and instead of, and I'm trying to make it call, instead I'm trying to make it use this ID instead of the ID up here, okay, but it's not going to, okay. Yeah, it's not going to log it, it's going to, because the ID was bound lexically, even if I try and override it, it's still going to use this ID, it's not going to use the ID I'm trying to cram down it's throat. We get it, we're seeing eye to eye? Proceed? Alright. The chat was asking about call applied by, but you've already touched on call here. Yes. The same generally applies. Yes, yeah, so. Even if you try and override it, you're not going to get it. Right so it's bound.
Functions vs. Arrow Functions
(Music) Do you have a question? It might have been covered, but so you're saying you can't use .call or .apply to dynamically set this? True you cannot, well you can try to, you won't get an error, but it won't do what when you look at it you'll be like, oh it's going to override the this and use this as the this, but it's not going to do that actually. Can you, like. I just wanted to say this eight times in one sentence. Be like if you bound something twice. Yeah it's only going to take the first time. If you bind it twice? If you said .bind, .bind, .bind, because the result of a .bind is a function, so you can bind .bind but it's not going to take that second. The second one. Yeah. Same concept here, right, yeah. So okay. So was someone else asking a question I skipped, I don't, I didn't mean to if I did, I'm sorry, okay. Still use functions. So let's go back to our widget guy and we've got, we got a function on our init, right, init's a function. We agree? Okay so what if I I'm going to copy this to the traceur repl. (working) Can everyone see this okay? Everyone see this code okay? (working) Okay so I'm going to change this to be an arrow function instead of an anonymous function. Just so we can see why you're still going to use function, a regular functions. So I'm going to say blah, wait I'm not going to say that. I'm going to say Ha Ha, okay. I'm actually going to refresh because we have, every time I type, it's adding another bloody click listener, so actually going to refresh real quick, just to get rid of the fricken listeners. Okay, so you guys see what happened when I clicked the body? It can't find, undefined is not a function. So it's trying to do, it's trying to do something on the this. So why don't we do this real quick? (working) So what's this? Window. Yeah, yeah, yeah. So we've got, we've now got this new, we've got this new this that's the window, okay. And the reason is, is because when it was going through the code and it was setting this up and it was like, okay evaluate that line, evaluate this line. Evaluate, don't execute it yet, just fricken load it up. Get this, put this on there. It had to bind this function, init, to whatever the this was at this context. And what's, when the page is loading, what's this? Like when it's just going through and parsing everything, what's this? It's the window, right. At least in the browser and in node it's not the browser, obviously, it's not one of, but anyway. So it's the global, but. So it's going to bind all your individual widget functions straight to the window, which is stupid. So yeah, that's exactly what we're going to do, because the window doesn't have a do something, the widget has a do something still. And if I change this guy to also do it, guess what, the window now has a do something feature. Okay? Yeah, it's still not going to work. Anyway, my point in what I'm trying to show you guys is you're not going to just replace all functions with arrow functions, otherwise you're going to be like who did this to my code? Like I don't know how to do this anymore. So yeah, just like know what it is, be cool with it, accept it for what it is. And use it where you need it, don't, I mean anywhere where you would have said var me equals this, or you would have used a bind, you're going to use this, okay. And new people coming into JavaScript and they see this, this once in a while, people use this function, they're going to have to know like they're going to have to explicitly learn why they're doing it that way. Just like he learned, I'm going to explicitly use function bind and why I said I'm going to use var me equals this, I'm going to like save a reference to this. Because we had to learn on the fly and so, people coming in are still going to learn to use when do I use a fat arrow function, or an arrow function versus a regular anonymous function.
Exercise: Arrow Functions
(Music) So let's have everyone try some noni functions out. So these actually work in Firefox, so you guys can go ahead and try them out straight into your Firefox console. They also work at the Traceur repl like you saw me using them. But go ahead and try them out inside an object, try them with some event handlers, and then try them with like try passing some arrow functions to like an array map or an array for each or an array reverse, see if you can, not reverse, see if you can figure out how to dork around with that stuff, so. Good? A couple questions here. Yeah, yeah, yeah. Is this a good spot? Yeah, yeah, yeah this is a great spot for questions. So the arrow function in ES6 is different than than the one used in Copyscript? So Copyscript has two arrow functions and they have a skinny arrow, which is instead of the equals sign, it's just a hyphen and then the greater than. So and let me show it here. So in Copyscript they have, oh bollix. So they have this kind of an arrow function. And then they have, so they have those two arrow functions. And in Copyscript they built them for this purpose, like this is why they have two of them for exactly what we're talking about. And you use your skinny arrow functions wherever you would use an anonymous, just a regular function. You don't care what the this is, you just need the code to execute when you do. And then they're like, well we have this time where we need to bind stuff, like it needs to be scoped lexically to the this. And so they're like well in that case we'll create this second arrow function, which is a fat arrow. And so in Copyscript you have to learn and you have to read and parse with your eyes, that is a skinny function, that's a fat function, which one of the two is it? And so this actually does work just like Copyscript's fat arrow functions, it does not work like Copyscript's skinny arrow functions. So yeah. Why is the parsing different? Like because with your last example where you change the like the net function to be a fat arrow function instead and then this ended up bound to window. Yeah. Like, I thought Copyscript parses that differently so it would have worked the way you expect? I don't know man, I'm not a Copyscript guy, so maybe someone who's used it, maybe on the live stream can tell, but I don't know what Copyscript would do. I would imagine that if fat arrow did what I've been told it does it would break, but it may work, I don't know. Another question, are there any performance improvements with the arrow function? That's a good question. Why didn't I talk about that? Oh man you got to stop all this. I just got here. Okay, so it's not, it's not like strictly sugar, right, like it is sugar because it's going to bind the disc for you, which is nice. And it takes the word function out and it gets rid of the return statement. If you only have one line, like, so it is a little bit of sugar. I'm going to say mostly sugar, but combined. So remember how we said you can't new this up, like you can new this guy. Combined with classes, there's like a potential long term benefit of having these kind of functions and that is, so right now we have functions and every function has like this constructor thing on it that so that you can construct it if you need to. And I'm not, like 100% into how much weight that takes up in memory, but I mean it's not nothing. And so if every function, if you could get rid of these constructors on every single function, because most functions, I mean like almost all functions aren't constructors, they're just methods, right. And they, I'm not ever going to new up my click handler, like, it's just a function. And if there was a time where all constructors were only used for the class syntax and functions were only used as functions, but not as constructors. You could conceivably remove the constructor binding from a function, which might make it lighter weight in memory, which could potentially have a benefit of a runtime in that it wouldn't take up such a big memory footprint. But again, I'm talking about something I read one time, not that, like I write JavaScript engines, right so, because I don't, so. One other kind of question here. Object function, so object functions can be defined by skinny arrow functions? But I think skinny arrow functions are only in Copyscript, right? Totally, yeah. I think that's what they're saying. Yeah skinny arrow, like the word fat and skinny that's not ECMAScript thing, that's purely Java. I keep saying it, I said it so now you guys are going to go say it, and I feel bad, because I didn't mean to teach that habit. They're just arrow functions. And then someone on the live stream's obsessed with it and so we've said it like 10 more times. But again, it's not called fat arrows, they're just called arrow functions, okay. Let's code up destructuring inside of an array function, should we do that? With default parameters? Alright let's try it. Let's try it. So let me hide the runtime or the generated code, okay. So I'm going to make an array for now it's just going to be of numbers. (working) Alright so we got numbers. Does everyone agree? Okay. And then we're going to say nums.foreach, or should we map? Let's do a for each, it doesn't matter. Okay so we're going to do a for each on these guys. So in here we're going to have this parameter and we're going to do our arrow and. Can you bump up the font maybe like one or two? That good? Okay. So in here we're going to say this is the num and we'll default it to a 1000. In the for each it passes, does it pass a second parameter, which is the index? For each, yeah. It does right? Yep. Okay. So I don't think I can do index -1, probably not. Let's try it though. No I'm going to do index +1. Your experimental's turned off I think. Oh was it? Do I need it on? For the defaults wouldn't you? I don't think so. Mine's working without them. Hold on.
Default Parameters, Classes, and Collections
Default Parameters
(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) So we're going to move onto classes. Who's stoked about classes? Let's see, I got one, I got two. Classes sound good, let's do some. Three alright we got classes. Are you? You know what I'm going to, I'm going to be honest with you. I wasn't, you know because I come from, I started working in Javaville where it's like, horrible service implementer factory service in bowl proxy. And you're like what? Why did you name it that? Like that's the worst possible name that you could have named it. And so I'm like dude Java, if I ever have a JavaScript object that's named com.frontendmasters.services., I'm just like, I'm just going to, I give up I'm moving to another country. Like it's, I don't really want to, I got really scared that was going to happen and it is going to happen, like who doubts it, who doubts it? No just for the record no one raised their hand. It's going to happen and so I am nervous, I am nervous about that. I think the community though will fight it back and keep it down a minimum, which I got over it. But then once I learned you can extend to like built in functions like built in objects, I was like that could be cool. Like an array, I could like make a my array and it just extends array and I could, I could make the array.push function. I could make it return the array itself. So I could daisy chain like .push, .push, .push, you know like a, I could do a bunch of things like inline. What you can't do, right now you have to do like array.push, no blah.push, you know what I'm saying? So like I could extend it and do my own stuff. Maybe I could make, I don't know maybe I could use classes to make something that's easy to read, because let's face it, well I'll get into it. But, so now I'm actually pretty excited about it. Does that count? Okay. Alright, I don't think the chats listening so let's hurry. Okay, so history of classes in ES6, it goes back to the ES4 days and we know this because Adobe's like, we're just going to implement it on our own. There's been lots of churn there's lot of precedencies in most other languages to have like a formalized class system and not prototype inheritance. So they're sitting and they're like, fighting right, and we've talked about the big gap and the fallout and it's interesting, Brendon and I actually this is a little tidbit I'm going to tell it fast. I can actually, when they fell out and like they couldn't agree on anything and it was just like a fight, he actually calls that like a fellowship of the rings. Because he's like, you know how the fellowship of rings they're like we're all going to do this together and then they all go their own way. Like he's like it's the fellowship of the ring, we all end up breaking up at the end. And it's funny, one thing I didn't tell earlier, so ES3 camps got to give up and accept ES4's proposals, right. Or the other way around, the ES4 camps got to give up and accept like to push ES4 and just do the ES3 stuff for now, right. So that's what happened was the ES4 camp's like cool we give up we'll do the ES3.1 thing for now and. So Microsoft is in the don't do ES4, let's just do the 3.1. So Alan Worsbrock he comes over to Mozilla after that, he's at Microsoft goes to Mozilla. And he's like dude we almost gave into your demands, like we were about to give up when you gave up. So like, just like, we were like this close to having all this stuff back in 2008. But you know the cards fell like they fell, and we're at where we're at today. So anyway, so there's a lot at the hardest conflict is like this strong type system and getting something going and they still to this day cannot agree on it. Like and when they can't agree on something remember what I already said when the TC39 they can't be like this is how it works, clearly that's how it works. What happens? It gets pushed to the next release, right. Like so, and they were like eight classes were never going to make it into ES6 ever, okay. It was just not going to happen. But then Russell Leggett he sends this email on March 19, 2012 and he's like, hey you guys should read this, it was an excellent email, okay. And he copies a bunch of code off of Copyscript's website and he really kind of just like was like hey everyone chill out, like this is what I think we need to do and everyone, not immediately because there was like a lot of discussion if you click on the thread. Like this is where the thread starts and I mean it was a huge thread that month. Everyone's in it. And it's like the big names, Brendon and Russell, and Alan, and Dave Herman. Like dude's who, I don't know, epic dudes. Anyway. So it was like a, it was a cool email. And if you want to, go back and read it, but this is kind of what he talked about. He talks about, he calls it maximal/minimal classes. Maximally, I forgot the Y, maximally/minimal classes. And he points out the need for classes, he's like dude look we have needed this for so long, people invented things like Copyscript because we've delayed so long. So like he kind of points out, there's a series, the people are doing compiled to JS stuff because of it, right. And we have like typescript and stuff. So he points out a strong need for classes for something that's not the prototype stuff. And he's like, we get, and it has to be enhancable by future releases. So whatever we do release, it has to be minimum viable that we can extend, okay. If anything's not extendable we have to cut it. Or if we're not a 100% sure on something it's out. And everyone's like, okay that's cool. And he points, he points to Brendon, because Brendon's over there and he's like, hey we got this, you know, he called Brendon's proposal the goldilocks proposal. Because he's like, you know it's not too hot and it's not too cold it's just right. And that was Brendon's point of view, he's like not too much classiness, not too little classiness, but like just the right amount of class syntax and we're good. And they could never agree on that, so he comes up with his safety school proposal. And so the safety school proposal, he's like in the states we have this idea of you graduate high school and you send off your applications to like the school's that you want to go to, right. Who did that? Like I didn't but maybe some people did. And he's like by then you always have like the safety school. He's like so when all the things say no you have this safety school and you can at least go to the safety school. He's like, that's what we need to focus on is the safety school. He's like, we got to come up with the minimum viable product that we can release. I know you guys want, it's like an Ivy League class system, but what's the safety school system look like, what is that one? And so that's kind of what he proposes out there. And he's like if we have to have something ES6, so what is that, like what's the things we can agree upon, SANS, the stuff that we can't. Like let's just talk about what we can agree upon. And so he wins out, obviously I showed you not easily, it was a real long conversation, but he did win out. I mean people pretty much adopted that safety school proposal, the maximally/minimal class system. And that's, that's what got implemented, it was that. So the things we're about to see are the things everyone agreed on. The things people can't agree on, we're not going to see that. So everyone's going to be like hey what about the thing and I'm going to say, well it's not it, it's not a thing yet, it's still being discussed. And if there was a feature that you're not going to see go ahead and call it out and let us know, but there's a lot of stuff not here. But I'll try and show you the stuff that is here.
Class Syntax
(Music) So like again I showed you this earlier today, I'm going to go back down to the bottom in case someone didn't see it. But like even here on this class proposal, like they are like, hey be warned, be ye warned. If you even think about modifying this spec, it will kill it. Basically, like if you read this that's what he's saying. Don't, don't, don't. I know you want to, shush up, you know he's like just don't like push it to the next release, we're releasing this. And everyone kind of agrees. So yeah that's where we ended up. And that's what we got today is we got this maximally/minimal class system. So here's a class. This is what a class looks like, okay. These guys are functionally the same, okay. So I showed you this because I wanted to point out that the class system, the class system is only sugar on top of things you can already do today. Then we're not going to do anything right now that you can't do today, okay. And so I think you know we should, we should state that upfront. I think it's a little bit more elegant in the class syntax and I'm going to embrace it until we start seeing crazy, crazy. And the first time I see an impel in JavaScript I'm out. So, so yeah. But yeah, so functionally these are the same though. I can new the both up, they're both going to execute when I call new, this is, this is the same thing, okay. Again remember earlier though I said if we got rid of all function constructors and only had class constructors than functions could be lightweight long term. Which means they could take up less memory and less foot printed memory, which means JavaScript applications could potentially weigh less and maybe run faster. So the long term performance, what I mean, we're not getting rid of constructors on functions for years, right. Just because of Legacy, but it could potentially if everyone only used class stuff and like maybe they do some opt in some day in the future, where you're like, I opt in to never use function constructors and only class constructors. It might be able to have some performance gains, but for now it's just sugar, okay. Alright so a class has a constructor function and it's just called constructor. Other languages, if you have a class called foo, what you're constructor called? Foo, right. So in here it's constructor, right. And if someone passes in, like if I have this animal class I make a constructor called name and I can say this.name = name, right. Again, can you do this in a JavaScript today with functions? You can right? Like easy. So I wanted to kind of point out private properties because a lot of people were like dude private properties so cool. They're alright, I mean it's not amazing, they're only kind of cool and it's really only private because of obscurity. So who here's familiar with symbols? You are, okay. I'm going to do, I'm going to use a symbol in the console real quick just so you guys can kind of get what it is. Is that big enough, can you guy see that? Var, so I'm just going to say new, no I don't have to call new, symbol, (working) come on man. Dude why aren't you working? Why isn't my symbol working? Okay so screw this, let's go to. Is it a constructor? No it's just like, you just call it like that it's like a static function. Actually Traceur doesn't have it don't think, maybe it does. Okay so this is what they look like. They've kind of, they've kind of got like a wonky value so it's basically like making a unique ID, right. It's kind of like having a GUID generator, okay. But make sure you don't have two of the same one. So then you would have like your own, you would wrap all your code inside of an IIFE or instead of a function, inside of a closure so that people can't see. So okay sorry, I'm getting ahead of myself. I'm going to go back to the slides.
Private Properties
(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
(Music) So when we get the health, so the health is not protected behind this obscurity pattern where people won't be able to see what the key is to get the health out or to manipulate it. So I'll set the health, you know, they'll be able to get the health out and then they can say, get.isalive, so they'll be able to just call say monster.isalive and it will return if the health is greater than 0. So you'll be able to know if it's alive or not, right. And like you could make it an attack method that could like pick some random number between 0 and the amount of points remaining. And like it does some calculation to subtract some of the health left and then is alive could fire something else or. And you could, anyway yeah. So does that make sense? Like you could make one that says like alert when dead that returns a promise, oh we didn't talk about promises yet. Anyway this is the syntax. Sorry I'm getting, I'm nerding out on the monster concept, I apologize. I've got a three-year-old and we talk a lot about it at my house. Okay. And how do you call the get function out, just normal? Oh yeah, yeah, yeah, yeah, good call. Let's copy this back over. Copy Traceur and then we're going to change this to var so it doesn't freak. And then we're going to say var kevin = new monster kevin and we'll give him more hit points this time, right. And then we'll say alert kevin.isAlive. So when you use that get syntax you specify it as like a method call, but you treat it like a property. And this is part of ES5 spec they have like a defined own property. And it's kind of like getters and setters for JavaScript. And you could do the same thing if you wanted to, you could be like set isAlive bloody thing. Hold on I got to kill him. And then we'll just be like if not alive this sub monster health is equal to 0. And then we could say, kevin.isAlive = false. And then we can say alert kevin.isAlive and he's dead, we killed him with one Voldemort thing. I hope you feel better? Yeah I do. Anyway does that make sense how the, if anyone, if you're not super familiar with getters and setters properties, check them out, they're pretty cool, you should start using them. But yeah, good question, thanks for asking that because I didn't include it in the slide. I'm sorry and one more. Yeah. Can you also do it with this.isAlive to support for an interclass or it is done more externally? No, no, no, it totally works for more than the class. So like yeah let's do that. I'll actually show you a weakness in the current implementation if you want that they're not going to fix. How awesome is that? Shhh quite down you. You go away, you come out okay and you go away. Okay so we're just going to make a property, what did you want me to do, what was your question again, sorry? So I asked, if you can do this is alive instead of just. Yeah, yeah, yeah, totally. So we'll say foo, so now we have a method foo on our prototype, right. And we're going to say console.log("FOO", and this .isAlive) And then for that (working) someone wants to know I'm alive and then, so we're just going to call Kevin.foo. So when you called, when we called this it was like am I alive and he's like someone wants to know if I'm alive. And then he logged foo.true and then you have it. So you can totally do that. Awesome right? Yep. Okay, who's ready for an endless loop? Okay, I'm ready. I'll show you because we're friends, okay. Alright. Alright I'm going to delete these just because we're done with them, okay. So I'm going to say, set name(name) this.name = name. Who can see the problem? I mean it's down here in red, who can tell why that's happening? Can you guys see it, sorry? If I blow it up it's going to go off the bottom, so you pretty much got to get what I can show you. It already has a name property assigned to it and you're assigning to it another name to it. So when you call set name, yeah, so right here he's going to, he assigns this.name = set name. Well this .name is a call to this function right here. So he sets name, he does the same thing, he's like well this.name is equal to whatever name is being passed to me, so I'm going to call this and pass that, which is going to do this and call that, which is going to do this. So you're in an endless loop, right. So that sucks. Can you do it? Yeah you can totally do it, you could probably do it in ES5 today anyway, so. It's probably not a thing you need to classes. I just noticed it when I was testing this out because I'm not smart and I did this. And I was like oh yeah that was stupid of me. And I did it, so. Good question. You can do this stuff in and end up in a cyclical death trap. So, we good? Yep. Okay. Alright. Okay set health and I can pass in the value and then this is how you set it by using that same key that we talked about above. So you would call monster.health = 100 and it would pass in a new health. Attack, you could pass in another monster and you could say, so Kevin attacks whoever our second monster is, right. And it would log that if you called Kevin.attack and passed it another person. Which we may attack Kevin if he keeps it up with the thick arrow thing, right. Or was that not Kevin? That was like Seth or somebody, huh? Okay. So yeah. You can have static properties, like every time you create a monster if you wanted to add yourself to the all monsters array, you could go ahead and push yourself into the monsters.allmonsters array. So that's a static property onto the class, okay, so you can have static class properties if you wanted to do.
Extending Classes
(Music) You can extend it, so if we make a monster called Godzilla, for him we can just call the super method and pass in Godzilla and 10,000 because we all know Godzilla's pretty tough, right. So yeah, so. Sorry I'm skipping. So, yeah you could totally extend like that. Is this something you could do in prototypes? Has anyone ever done anything like this in prototypes? Yeah. Some of us have. You can totally do all the things we just said in prototypes, okay, so yeah. I just wanted to point that out real quick that this is definitely not a new thing, this is still sugar. The extends, the extends expression can be like a method call, it's just going to be evaluated. So like you could say, class mySocket extends getClass and then a getClass says well if I'm IE use my IE web socket implementation. Because you know someone's going to do it and then otherwise return web socket. What's up? Does the const declaration have to be outside of the class declaration? For? I think he means for the symbol? For the symbol? It has to be because if you put it inside the constructor, oh I mean okay, well I'm going to go back to the code just because I think I know what he might be asking, okay. So in, I'm going to delete this code down here just because it just messes things up, it just makes it look dirty, okay. So in other languages that have this kind of class syntax, you have like room up top where you can be like, you can make a bunch of variables. So like in Java when you have a class your first few lines, you can put like some constants up there, right. And yeah so I think he's asking can he say var monster, can he put this in here is basically what he's trying to say. Correct me if I'm wrong, is that what he's trying to say? That's my interpretation. Yeah, yeah, yeah, no you can't say that. I should've just said that, but I wanted to make sure I was understanding what he was saying. You can't do that. Yeah and so this actually, this brings up a good point, so this is one of my biggest grips about JavaScript, who here works with Angular? Yeah. So I'm an Angular guy and like I'm going to just ask you to think about like a controller function real quick. Think like, even in the like the best code people do like at the root level of their controller function, they do like code, code, code, they declare a function, more code, code, code, more function, more function, code, code. It's like who wrote this, like whoever thought that that was an okay way to write code. The fact that you can write code, like at a root level, makes me just want to like stab myself. And so I really like that in classes you can't do that. I like that in classes here it kind of takes, like there's no root level code here. You have to put it all inside of a method, that's not what you did in other languages and that worked great, right. And so I really like that it is bringing a little bit of structure back into our code not letting us just like pepper it in wherever we want. I think this is a good thing. So, so yeah. Anyway but I cannot do what that guy wants to do. So at least that I know of. And that's just today, you know, the spec could change, so yeah. Yeah so again the class, when you extend something, that could even be dynamic, like that can change per browser. So you could say mySocket extends getClass and the getClass says hey man if I'm in IE return this other class, otherwise just use the web socket native web socket. And so, so yeah. Does that sound like fun? But you could do it, that's the thing that you could do, you don't have to do.
Additional Class Features
(Music) There is some, remember how I said it is a little bit up for discussion still. Take a look at it real quick, I'm going to zoom in on it. So around the calls to super this might change a little bit. So what they're thinking is and I actually wanted to ask everyone here because I just barely found this out. And I just barely found it out because they just barely are talking about it, like this is brand new, this is still subject to change on classes. So when like when we say this thing's still being talked about, it's totally still being talked about, you know, as we speak. So the thought is, if I have this Godzilla class that extends monster, and someone calls attack on Godzilla, and I want to do some Godzilla things, but I also want to call my super, my super's attack. Does it make more sense just to call super? Or does it make more sense to call super.attack? That was what I wanted to ask you guys, because that's what currently up for discussion. So the argument is, well if you're in the attack method and you call super, it should look for the parent class and just call the class, the function of the same name. That's what some people are saying, so they think that the super, just calling super is good. And other people are like, just dropping the word super at random places doesn't make any sense to me I want you to make me say super.attack. So what do you guys think? What if you're wanting to do a different super functions, right, like? Like how this prepare to attack method on super? Well you could always call if it's, if it's a different function name you don't really run the risk of calling this.prepare for attack. Right, you would be fine if you said, you could say this.prepare for attack because that's not cyclical, that's a totally another function. But if you, we're just talking about the two that are called the same thing. If I call this.attack I'm F'd right, because this is just going to start all over. So the question is specifically around the two methods called the same thing. I prefer the first. You prefer the first? Yeah, yeah. But if you're overriding this with the attack function but what if you're super class doesn't do certain things that you want the attack function to do. Like if you attack you also want to subtract from your action point, but you have separate function that would subtract an action. Totally bro. You could do super. Exactly. And if you got like a really good dodger that was like hey dude I'm going to like dodge stuff as I attack, I don't know, like so. My attack method here is incomplete, you could have more code besides just calling super. Like I could have code that like do a million things and then call super.attack. Well what if you just want to call like three super functions, but not have any of those functions on your extended class? That's how you'd call this style. Yeah I see what you're saying, and if that's something that would make sense, and I'm not sure that it does, and I'm not sure that it doesn't I just haven't thought about it. But if that was what it was then the super.attack would be better, right. The dot syntax would be better than just the super syntax. Anyway, you guys see these guys these super smart people, they sit at the TC39 things and they're like, they talk about that, like at length. We talked about it for five minutes and I'm done, like I already want to give up and go home. They talk about this and they email about it for like days, okay. So this is what the TC39 does. So this is something that's still subject for change, which is why I'm not going to teach it to you. Like I just wanted to point it out that that's the thing that might change. Make sense? Okay. Alright. You can't use it before it's been, it's like let, like it's let like. It's not going to, okay. What I meant to say is it's not going to get hoisted, okay so. If you have class bar on line 10 and you try and new one up on line one, you're going to get an error because they don't hoist. At least they shouldn't hoist, you guys might try it out on Traceur and it works, but they shouldn't hoist. So if no constructor default behavior, yeah so if you don't have a, if you don't have it as a constructor like let's say you just make a class called foo and you don't give it a constructor. Or you're like, foo and it extends something else, if you don't give it a constructor it's going to do the same thing that we're used to other languages doing, which is just calling the super constructor and passing it the arguments. So that's all it's going to do. So it will implement default behavior when a constructor's absent. Benefits of classes, we talked about it sugar. I think it's easier to learn for noobs too though. Like some of us have like really honed our skills on prototypes and I sometimes like look at my classes, my prototypes and I'm like, that is beautiful. I've done a great job today. But I think for new people, for people who are just learning the language, which hopefully we get a lot more JavaScript learners. I think it's a good thing, I think classes will help. I think sub, especially sub classing specifically I think will make it easier for new people. You can also subclass built in stuff, some of the benefits. I think it will make code ports between languages a little bit easier too, just to compile. I think it will make JavaScript a better compile to language, personally. And I talked about the possible perf gains long term if we got rid of function constructors and only used classes, you could see some I don't know, I think big, big performance gains if all functions lost their constructor. But yeah, that's classes, we did it. We good, any questions? Online? No. Okay. Let's go ahead and try it out real quick. So go ahead and try and like build something in parallel, a prototype and a class. Or like fourth, for some method implementation from super, try that. Maybe someone could like extend array and make it so that calling array.push returns the instance of the array so that you could like chain your calls to it. You know what I'm saying? So you could do like, kind of how you can in lowdash, like array.map.filter.blah. Well actually you can with those ones, but not with like push and pop, but anyway.
Collections
(Music) Three collections, sets, maps, and weak maps. You guys read a bit about them? Okay. They're kind of like, they're kind of like things we already use today, but they're different so we're going to explain them a little bit. So set is like an array, map is like a key value object that we normally use, and then weak map is like a map but still different still, so. Let's talk about each one. So sets, we're going to cruise through them. So set is a unique collection of things. And it will make sure that they're unique. So I just say, new set I can add 1, 2, and 3. I can log the set size, it tells me there's three, okay. The reason you'd put something in as a set is because a set has a .iterable on it, or a .iterator. And you can do some things with iterators and for loops and stuff to get things out of them efficiently. So that's why you'd put something in a set as opposed to an array. So it forces unique values, so if I call set.add and I give it 1 three times, the length is still 1, it didn't add it three times like an array would have. So if I make a set, and I'm going to highlight just the code here, and if I say has 1, it's going to say false. And then we add one and if I say has 1, it's true. So I've now taught you has and add, so now I can call clear, and if I say has 1 it's false again because it cleared out the set. So the set's now empty, that's how you clear out a set is with clear. I can add 1 and 2 to it and it will tell me the sizes too. And if I delete 2 the size will now be 1, okay. So this is kind of the, these are kind of the methods that you put on them. Yeah? Okay. There's no type casting for uniqueness, so like you might expect it to say maybe a 1 and a string 1 are the same, but they're not, right. So like if I add 1 and if I say has 1, it's true. If I have a string 1 it's false so it's not going to type cast that. A lot of things in the past have like type cast strings and numbers to be interchangeable, but this definitely doesn't. I can then add one and it will have one at that point, so yeah. To iterator over them, if I make a new set, and again see how I did this, I passed it an array but you can make a set out of an array or you can do that add syntax that I showed you to put things in there. This isn't supported everywhere, so like Chrome has got sets, at least some Chrome has got sets because my man's Chrome's didn't have sets, but I swear I had sets the other day, I could be crazy though. So some of the constructors don't support this though, so if you try and make a set like this, like from an array, it may die. Actually it won't die it just will ignore it. So it will still run, I don't know which one's more dangerous to be honest with you. But there's a new kind of for loop here in JavaScript that you're going to, in ES6 that you're going to see. It's a for of and if you have an iterator, if you have something that has an iterator property, it will sit there and it'll iterate through each of the things in there, okay. So yeah, iterators are, iterators kind of go hand in hand with generators, but it'll just iterate one by one through the set.
Collection Maps and Weakmaps
(Music) Okay maps. Okay so JSON I just make a map like this, right, the very first thing. I say name is Aaron, right. Well in a map I say, I make a map and I say map.set name Aaron. And I can say map.getAaron or name and it will give me Aaron back, okay. So that's how you make a map. So you get map.set and map.get, again there's no type casting on them, so if I say map.set1 and I set it to true, if I say has 1, it's going to be false. But if I then set 1 and it will has 1 at that point too. So does that make sense? No type casting. Because like on an object, on a JSON object it's going to type cast, right. So if you say object sub 1 it's going to cast that to a string and make a property on the object that's called 1, right. So this, this is not going to do that. So this is like a JSON object, but these two things would both be treated as separate keys as opposed to two, the same key. So the old way, if I take a user, so let's say I create this user and maybe I got this user from the server, maybe I got it on local storage, I don't know where I got the server object, I got it from something though, okay. Something gave me this user object. And I'm going to make a new map for user hobbies, okay. And I can actually use an object as the key, okay. So for hobbies I can put in there and the key can be the user, so instead of having to like go through and like reference it based on ID, and use primitives only as the keys. You can use objects, functions, primitives still as well, but you can use complex objects as the keys, as opposed to just primitives. So here I have a hobby map and I get my hobbies out by just passing it the user. So I would say, map. or user hobbymap.get and I'd pass it my user and it gave me back my hobbies, so. That's one thing you can do. So it can't be like a second copy of an object that like looks identical, because here I've got two users that look a lot alike, right. Like and by a lot alike I mean they have all the same values, but in memory they're two different objects, right. So if I make this hobby map and I set user 1 and set his hobbies if I try and get user 2 it's going to be undefined. So even though they look alike, it is completely separate key because it using the pointer instead of the object itself. Does that make sense? Okay. So yeah. And then a usage, some people were like hey I'd like to make a bunch of, I'd like to make a map of my DOM elements and put them into a map so that I don't have to keep querying them and I could get their properties just by referencing them themselves. So you could go get some element off of the DOM and you could say, you know, you could set element and you could say load it, it's true, opacity is 0, right. And then later on some other section in your code you could get the element back out, right. So why is this a bad idea? Does anyone know? Can anyone think of it? It's all my change. It's all my change, right. Yeah so something happens and the DOM changes. Anything that's not in my map, memory the garbage collection's going to go, I'm going to kill that, he's gone. Just because you remove it from the DOM doesn't mean it's not in your JavaScript memory, right. So if you've thrown all these references to DOMs inside your map, now we suddenly got a problem because you had a huge memory leak because anytime the DOM changes you're still flooding out memory because you're packing them into your map. And this is a problem, right. Okay. I'm going to talk about why this is bad, I'm going to show why this is bad in a second. The one last thing I didn't show about our map and let's just show it real quick, (working) There is a question in chat, I don't know if you want to do it after you're done with this or? Yeah one second. So you can get a map iterator out of it and you can iterate over all the properties inside of the map. There's not a size is there, yeah? Oh yeah there is a size. So you can, you can like pull the size off of a map as well just to see how many things have I mapped out, how many key value pairs. So yeah what's the question? Do you see the chat there? Yeah, so it says can you provide a custom? There's one right before that and then maybe you can ask that one next? The one by James G? As I understand let is occupying only one position in memory so we can't use it with map. Set because they always have more than one value, is that right? Yeah I'm with James G, I'm not sure that I understand the question. So I'm going to go to the next person, I'm going to go to the next question. Can you write a custom hash function for sets and maps? Robby I don't know what a custom hash function is. I think he means like to tell what a key is, like in Java you can pair whatever the other languages is, sometimes you can control a get hash such that like it's not just based on the object itself. Like you're, it could be unique by its name plus value. Oh yeah, yeah, yeah, yeah, not really like not built into the framework, you would just make that the key, right. So yeah. Sorry dude I don't think so. So yeah, so the last thing I need to show is the size and that really matters because we're about to show a different kind of map. So I talked to you about like the memory leak that you're going to get if you try and put these DOM objects into a map. It's going to be efficient because you're going to be like dude this is actually really fast, but once at first, but then all of a sudden it's going to get really slow because you're throwing DOM elements into a map. The DOM releases it's reference but your code never released its reference. So garbage collection can't pick it up. Your map just kind of grows and kind of explodes. So a weak map is a different thing okay all together. So for a weak map is like a map except for it doesn't have that, it potentially can avoid that memory leak problem. So if we have a weak map and we set name equals Aaron, we can get name and Aaron comes out. So a lot like a map right. Has a user, so if we say has user, we'll say false, we can set the user it has user true. We can delete me, it won't have me anymore, anyway. So it's just exactly like the map, okay, that's all I'm trying to show here. But it's not exactly, not exactly. When I said exactly I meant not exactly, it's just a lot like a map. So inside a map, if you go ahead and set, like let's say we put the same user side of a map in a weak map. The map has a size that weak map doesn't have a size. And it's important because what that means is, it's not actually keeping track of how many things are inside of it, okay. Like it's kind of hard to explain, but if you put a key, like let's say my user key or let's say I get some DOM element and I store that inside my map as the key. And the value can be foo, I don't care, right. If my map is, like let's say the DOM and it goes in and removes it and so the only thing on the whole planet referring to that DOM element anymore is my map, my weak map anyway. If a weak map sees it's the only thing holding onto an object, it will release it, okay. So you can go ahead and you could set the key to be some DOM element and then once it's gone you're left being the only, your maps the only thing, your weak maps the only thing holding a copy or a reference to that DOM element. The weak map will let it go, okay. And because it only has a weak reference to it, that's why it doesn't know like how many things are in it, it doesn't know, it's size or anything. Does that make sense? But it's kind of okay because like if the DOM element was gone and you were the only thing pointing to it then there's no way you could like unlock it anyway. Like so it should get rid of it because like there's no other pointers to it. You would never have like the cypher to get it back out, because the DOM element was the cypher, right. Like that's how you could get it out, but you don't have any more, so. Hopefully I didn't kill. Could you if you have multiple weak maps pointing to the same key, then they'll still let it go or not? I don't know, that's a good question. Great question actually. Yeah? I think maybe the one that you did understand there, I'm just wondering why you're using it, do you have to use var instead of let when you're assigning map, weak, or set? No you don't have to. So you can use let? Yeah. Okay. I think that's right. I just doing it to be friendly, I don't want to freak anyone out with a let word. I don't know dude, I wasn't paying that much attention, it wasn't intentional let's just say that. Good question though. Okay a weak map holds only a weak reference to a key, which means the reference inside of the weak map doesn't prevent garbage collection of that object. Okay and that, Nick Zakas wrote an article about it and that was kind of, he summed it up and I thought that was an elegant way to state it. So if the only pointer is my map, the map gives up and says take it, okay. So if that element right there, if that's the only pointer to the element is right there, in where I've set it in my weak map, it just lets it go, okay.
Modules, Promises, and Generators
Modules
(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.
Promises
(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.
Generators
(Music) Okay what do generators solve? Let's talk about it real quick. So consider this code here. So we're going to say, set timeout and after 1 millisecond go ahead and log this. Just wait a millisecond and then log it, right. Is it going to wait a millisecond? It might wait as little as a millisecond, but is, there's no guarantee it's going to fire at a millisecond at all. It will at least wait a millisecond though, that's the only thing you know for sure is it will not fire in less than a millisecond, and so that's all you know for a fact. So then we have this foo function that we're going to call right here. And we're going to say, while I is less than 1E10, which is a gigantic number, go ahead and just go ahead and just log, just start logging stuff to the console. It's going to be awesome, just go ahead and log it all out. So how long is this going to run for and when we call foo how long is it going to take to execute? Anyone know? Along time probably, right, like. Longer than 1 millisecond. It's going to take way longer than 1 millisecond, right? So when you run this code this is actually, it's going to actually print out in this order. It's actually going to log all this stuff and it's going to block for however long it needs and then it will return control back to the timeout, so the timeout can do what it wanted to do. So when you say set timeout basically all you're saying is, you're up next. Like no guarantees when you're up, but whenever that is you're up next, okay. So this is kind of a problem and this is partly why generators came around to help. So what if you could pause that and restart it though? Like if you could say, dude why don't you take a break off for a second, as soon as you said pause, the set timeout would go huh, I've been waiting for like 5 milliseconds, what took you so long? And then it would run and then maybe you could resume again at that point, like if you could pause, stop blocking the flow, and then let everything through, and then take back over when you're done, that might help the flow. It might make performance look a little bit better. If you could though, those two things would switch places, right. The wait millisecond would finish before that, the for one. Because that wouldn't block the process anymore, okay. So generators enable JavaScript to be a little bit more cooperative on long running stuff like that. So this is the syntax for a generator. You make a function and you put a star before the name. Cool? You can put it after a function as well, you see what I did there? I'm switching the star back and forth. Apparently either one is cool. I'm just putting it on the, in the name of it, because it seems to make more sense to me like that. And then you, the other new syntax you gain is this yield guy, okay. So we've picked up this star symbol along with our name and then and by now you've picked up yield as well, which is a thing we hadn't had before. And yields going to take a second to understand so let me show you how it's going to work. Besides yield, this body of this code in this generator, it's just a regular method body with the exception of the word yield. So let me show you how you use it. So if I call this geni, it's actually not going to execute my code, okay. It just returned to me this generator iterator, okay, that's all it did. And so in order to execute it, I actually have to call geni.next and then geni.next is going to start the execution, okay. And the first time I called next it ran to this yield, okay. And what it yielded, yield is kind of like return, but it's more like pause and send this value back, okay. That's more what yield stands for. So when it yielded it went ahead and it yielded this one back to me, okay. So I now, it gave me back this thing that said value is 1 and done is false, I'm still not done, okay. So then I'm going to call it again, yeah anyways treat yield like return. So notice that when I called it a second time it yielded me this 2, so go ahead and return this to but pause, done's still false. And then the third time go to return the 3, so it didn't yield anymore so my generator's kind of done at this point, it's like yeah there's no more yield statements. You actually called return, so I'm done I'm breaking out of this generator code, okay. So if I call next one more time it just is going to return an undefined value. It's going to say, yeah you're done, there's nothing coming out of this generator. It's not generating anymore, okay. So if we call this, it's going to go ahead and it's going to log 12345 but not 6, okay. Because when you call foo, what does foo give you back? Do you guys remember the terminology? A generator iterator. So when you call the generator function it gives you back a generator iterator. I wish there was a better name, but there's not. So it gives you, and then this for of syntax, do you guys remember the for of syntax? It will take anything that's got an interval on it and it will iterate through it, okay. Well the iterator only returns something if done is not equal to true. So when we, when it returned to this, done was true, that's why done, that's why 6 didn't locked, because done was true. So it just kind of, it's kind of like a no op on that thing. Does that make sense? Okay we're going to take it to the next level real quick. One more thing, so you cannot have a return value in generator function? Yeah at the end. Okay. I mean as soon as you call return, your generator function you got to get a new one. Your generator's dead. Like not dead, but it's done. But I mean if I would like to get the 6 sum, what should I do? You would yield the 6. Okay yes on the return, but basically that return value of the return gets ignored. Yeah and then on the next line you can say return undefined, I don't care, but yeah or just return a semicolon. So yeah. So yeah the for loops only continue on an iterator while done is false. So that's why 6 didn't get logged. Okay. So. Quick question on it, can you do a plus one to get the return, in that for loop at least? Plus one? Yeah so I guess. I don't even know what that means, yeah I don't know where you'd put it, but yeah. Yeah. I'm going to say I don't know what that means. If he, if you Tony if you figure it out let me know, if you know what he asked, okay. So now we've gotten like data out of a generator, so I've showed you guys how to like make it yield things back to you. Now let me show you how to get things into it. Okay, this function is super exciting, okay, don't kill me for it, it is an example. I'm just trying to show you how you can control some flow with these generators. Okay, so I made a generator and I passed it 5, I called next, it returned to me 6, I called next passing it 12, it gave me 8. I called next passing it 13, it gave me 32 and so I was like, let me walk you through what happened here. Because this code right here doesn't make a lot of sense unless you understand what yields doing. So I'm trying to explain what yields doing. Okay, everyone's got to focus though because this takes a second. I mean I know it's the end of the day, but like seriously bloody like focus on it. Okay. So we called foo and we passed it 5, agreed? That means that X is equal to 5, our incoming parameter is 5. We cool so far? Okay, but remember when we called foo it didn't actually execute any code all it did was set the parameter to 5 and return me a generator iterator, we agree? Okay. So now I called geni.next and it went ahead and it executed that code, it's in blue. It went ahead and yielded X plus 1, okay. So what's X plus 1? Who remembers what X is? X is 5, right. So it yielded X plus 1, so it yielded 6, so we got value 6 done false, okay. So alright, good so far. Okay now we're going to do our next one. So now we called next and passed it 12, you guys agree? So when we passed it 12, it went ahead and put the 12 in the space in where our code was, okay. So that's how I got, I get values into it. So I said, go ahead and call .next and pass 12 in. So what is why going to equal Why is equal to two times anything in these parenthesis, so what does it equal? 24 right? So Y is equal to 24, okay. And then it's going to keep going, so it's going to go ahead and yield back to me y divided by 23, what's y divided by 23 or sorry what's y divided by 3? You guys know, I know you know. I can has math, yep it's 8. So it's going to, it's going to go ahead and yield 8 back to me, okay. And the done is still false. So then I'm going to go ahead and I'm going to call next again passing it 13, which is going to set z equal to 13. And then it's going to go ahead and yield back to me 5 plus 24 plus 13, which is equal to 42, you can see it, it's in the slide. And done is true now. Oh my gosh, did everyone understand that? Tell me if I didn't have my blue highlights you would have gotten it? It took me a while to get the highlights in there, but it's the only way I could conceptualize it. So I figured it would make sense. So that kind of makes sense how generators work and again Kyle Simpson has got a bunch of generator stuff and one of the other frontend masters courses. So if you really want to dive into generators, check out his course. Okay. Is there a practical application of actually setting up the generator like that? Yeah check out Kyle's stuff. Okay. Mark say's he like genius on how it could be really really cool to fit the way we think. Yeah I mean his basic case is that humans kind of think the synchronously logic and reason about code asynchronously. And if you're coding with generators and he has some different patterns and whatever, you can write synchronous code but that are doing asynchronous routines. So yeah, I mean he does a talk on the things he recorded at HTML5.com all of this stuff for free out there. As well as the asynch, the last section of the events JavaScript course kind of discusses it so, yeah it's worth checking it out. Check it out, it's great for Fibonacci. Yeah it's great for Fibonacci. Godwin's law, we just did Godwin's law again. Okay so it has a companion feature called generator expressions and those got pushed to ES7. So they are not going to be in this, so if you heard about them and you're like dude generator expressions, they're out.
Build Tools
Build Tools
(Music) I got this LET class, okay, and I've got a generator in there, let.ja has a generator, don't ask me why. So you want to use a generator but you need it to compile into a language that even ES5 could speak, right. Because you have to support legacy, okay, cool. So I've got this generator class that's going to do this code and I want to compile it with Traceur now. So let me show you how to get Traceur installed. Can you guys see this okay? Not too big. Okay. Okay I'm going to see into source and see ES, okay. So the first thing you're going to do is you're going to say npm install --g traceur. Okay. So it just goes out and it globally installs the traceur utility for your computer. They threw on npm even though it's, yeah. So there you go, that's Traceur. So now from the command line you've got Traceur, so you can do Traceur things from the command line now, okay. And it's got, it's got a huge help file to kind of guide you through what it's going to do and if you have any questions there's a lot of help out there online, so a lot of people using it. So if you, and there's a bunch of flags you can give it, like if you wanted to not use for ofs, you can say for of = --for of = false, --class is true, stuff like that. Okay. So you can include it experimental stuff, you can include block binding, anyway. There's a lot of stuff you can do. So we've got this let.js, okay, and I'm going to go ahead and compile this into a generator real quick using Traceur. So I'm going to, let's clear this out. So I'm going to say traceur, I want you to write my out into samples.temp.let.traceur.js, okay. And the script is samples.let or let.js, okay. Does everyone see what I did there? I'm going to hit Enter, ahh, I hate live coding, but when it works, how good does that feel? Oh my gosh, I was so worried, okay. So now over here we've got this temp directory where we've got let., let's delete that guy because he's just confusing, so we got this thing that it just created and you're like, wow it made all that for a freakin generator? Well yeah. This is how Traceur makes generators work in ES5, okay. So this is what Traceur's all about, it's about making it so you can write ES6 and have it run in ES5 land, okay. So there's a problem though and that is like this line by itself, like let's say that this line, this file represented all of my code, from all, like all my libraries I complied it all into one line. I don't have the Traceur runtime so when it tries to say, dollar traceur runtime.do all these crazy things, it's going to actually freak out. So you guys are going to, are you guys going to believe I actually just forgot the flag to include the runtime, let's try it. Include runtime, fudge. Hold on, (working) what the heck. (working) So now I feel like a total putz, what is the thing. No not in the source maps, I don't care about the source maps right now. I could show you source maps, but I just, it needs to include the runtime so that, you can throw it in your index.html, but you can also have the build tool put in there for you, right. So you're going to need to put it on your page anyway, but if you don't have it, like if you haven't copied it in, you can make your tool copy it in for you. So, what is it, oh my gosh. Someone's going to like look at this and laugh at me. Anyway, okay. Sorry. It's not important. This is how, that's how you compile it, but we kind of need a more programmatic approach, like we're not going to sit here and write command lines, like commands to compile our stuff, right. So I'm going to show you guys grunt-traceur, if that's okay. So if we say GitHub and we're going to say grunt-traceur. So grunt-traceur is awesome, there's also a goal traceur, and then there's I think ES6 if I also could do traceur. But essentially how you run it, it's actually pretty easy. So let me go ahead and open up a sample project that I created. So we're going to do this grunt-traceur test. So we have this LET stuff here and we have my generators, we have a my generator, and we want it to compile it into this ES5 directory, okay, each of them. So I have this, I made this grunt file, who here's familiar with grunt? We got some people familiar with grunt, that's good. (working) Okay, hold on just on a minute mines just. So you have to add this Traceur config to your init config. And so I'm going to say include the runtime, use common js modules, have block bindings true, and experimental true. And for those who are kind of paying attention, when we ran Traceur from the command line and it showed us all the flags, those are options. So you can use those same options in here inside of the grunt plugin, it'll go ahead and break them out for you. And then so here's my build, this is my custom build. So I'm going to say go ahead and do, in the, from the current working directory, which is JavaScript, take everything that's .js and write it into the ES5 directory, a Traceur version of itself. So from here we can say, grunt traceur custom and it tells us, I don't know if you guys can see this sorry my terminal in web storms kind of small, it tells me that it compiled with LET that it compiled my generator. And if we come up here and we look in ES5 directory it went ahead and compiled it. So because I compiled them into separate files it went ahead and it included the runtime in both of them, which is kind of lame, right. So let's go back to our grunt file and say just go ahead and write all of them to the same file. So let's just say destination is app.js, we'll run it again, okay, oh bollics. I'm trying to, is that what I got to do? Anyway, I'm kind of like freaking out here on site because we're overdue and I'm trying to hurry and get it done. But using grunt-traceur this is how you'd do it and you, if you guys are like, hey I'm going to do this on my own projects, you'd make sure you have all the flags turned on. If you have something that's not working, you'd like, well generators isn't working so we're going to take it out, or I really want classes, so make sure classes is turned on. Get your, you know, you can turn source maps on so that if you get an error inline, like in this wonky looking code that it builds out for you, no one wants to debug this, right? Like this looks really scary. Well you can turn on source maps and so if there's ever an error you click on it and it takes you back to your original code. So how it makes it easier to troubleshoot, so. Make sure, and you get source maps turned on, but you can actually have Traceur as part of your build process and I'm guessing one day, once everything's solidified in more and Traceur's stronger, this is what most frameworks will do. Is have a Traceur build this part of their build step. So anyway you guys got an introduction to Traceur, go ahead and try it out on your own time though, write some simple stuff, like we wrote today, after each section. And try and get Traceur to build it into a file for you.
Wrap-up
(Music) There's a lot more in the ES6 release that we didn't get to talk about we kind of showed it off. Like I said a lot of these things were things we could take an hour on each, at least. So if we were to go through everything in here and really dive into them as far as we could, it would take, you know, it would take days. And so we tried to just bust through some of the more some of the stuff that I thought was super important. We didn't get into string.repeat or string.startswith or endswith, we didn't get into the string prototype. We didn't get into any of the array stuff, copy within, find, find index, we didn't get into any of the math functions or number.is and and some limitations on that. But, you know, those are all additions to it, I covered the stuff that you thought was going to affect the everyday developer every day, so. Any questions? And they don't have to be related to what we just talked about, you could ask a question about anything. How did you already try to use this with a framework, like Angular for instance and by, I know that Angular 2 is going to support, yeah, ES6 natively, but, yeah. Yeah so Traceur's actually implemented a lot of stuff for the Angular team specially. And so like you can get in there and see the, like voida is committed to the Traceur project. And they're taking Traceur pretty serious and they're, Angular 2.0 is likely going to be a compiled to thing. Just like, so if anyone's played around with React, you can do his jsx thing where it's like you're putting HTML in your JavaScript and then you have to build it into a wonky, like you could do it manually, but they just made it easy and so you have a build step you have a like a compiled time step. Which is okay, I mean, it's honestly not the worst thing that's ever happened to you. And Angular's probably going to have something similar and I think Ember's moving that way too. And so I'm thinking most of the stuff in the future that's trying to move fast and still support legacy is going to start having build steps, so. Most of the stuff we do going forward you're not going to get much further without having like a compile phase for your code, so. I actually meant did you already try to use it in the , no, no, no I haven't. But I dying to use classes, I think, I need to get some serious benefits out of classes in Angular. And like I said, you can do it with functions prototype anyway, but yeah anyway. Good question, any other questions? It doesn't have to be related to this, no? There's a question how do they get a hold of you? So on every slide I hoard out my Twitter account so you should be able to just contact me on js_dev on Twitter. And feel free to just tweet me and I'll try and help you out if I can. Definitely come, you know, punch me in the back of head if you see me at a conference in the future though that'd be fun, so. Yeah question. Somebody's asking you or talking about someone who has a good references on the generators subject. Yeah so his name's Kyle Simpson, he gave a talk at HTML5 div conf. And he's got a talk about generators, he also gave a front end masters course where he of all the ES6 stuff we went into LET quite a bit and he went into generators quite a bit. And so if you're really interested in generators, and I know a lot of you are based on the feedback, go ahead and check out his stuff where he spends, you know, a significant amount of time on that topic. Like I said, anyone of these topics, some of them we could talk about for like hours and hours and hours, right. But others are like good bite size things, but generators is one of those things where you really could go a deep dive and just thinking about all the things you could do with them and go around and ask everyone and then showing that off. You really could spend a lot of time. So the amount of time we were able to spend in here is just kind of, it was it wasn't as much as we could have spent. We definitely could have spent a lot more time on most of these features. So, so yeah. If you're interested check out that, that's for sure. But if you're also wanting to see what the changes they're still talking about with them, go ahead and check out the ES discuss notes. Like every month when they're talking about it. Those monthly notes have some good stuff. So yeah check those out too.
Course author
Aaron Frost
Aaron is currently an O’Reilly author, writing two books about the next version of JavaScript, ES6. The first book is for management, explaining the reasons why they should help their teams use the...
Course info
LevelIntermediate
Rating
(190)
My rating
Duration5h 24m
Released7 Apr 2015
Share course