 He stated, my name is Kevin Langley. I work with HumanMade. At HumanMade, we create WordPress applications for enterprise clients. So one thing I wanted to say just from the start, this is a very long talk, and there probably will not be any time for questions. So if you have any questions that come up, get with me afterwards, and we can go over anything. First, we're going to go over a brief history of JavaScript. So in May of 1995, JavaScript was originally developed under the name of Mocha. It was released in September of 1995 under the name of LiveScript. From there, it was renamed to JavaScript in December, and that was the release of Netscape Navigator 2.0. In 96, Netscape submitted JavaScript to the ECMA International for standardization. And in 97, this resultant in a new language standard known as ECMAScript. ECMAScript is the standard, and JavaScript is the most popular implementation of that standard and also builds on top of it. Other languages that also build on that standard is ActionScript and JScript. But as you can tell, JavaScript is the most popular. We don't have a learned JScript deeply course. ES is short for ECMAScript. Every time you see ES followed by a number, it's referencing an addition of the ECMAScript. So ES1 in 97, ES2 in 98, ES3 in 99. ES4 was actually abandoned. Then we finally got ES5, and this is what everyone is probably familiar with. This is what we had for years and years. It came out in December of 2009. And we didn't have any changes to JavaScript until June 2015 when we finally got ES6. ES7 came in 2016, and ES8 in 2017. Now you're probably wondering why isn't this course called ES8? The reason being ES6 was really where we got the majority of our changes. ES7, ES8, there was only a handful of changes that got added to JavaScript, whereas ES6 was the largest change that we have seen in the language pretty much ever since its release. And ESnext is a term for dynamic references to the next version of ECMAScript coming out. So the TC39 committee is responsible for evolving ECMAScript programming. They go through stages for every single one of their features that they want to implement into JavaScript. It starts with the stage zero of strawman, then the proposal, then the draft, and then the candidate. Without the TC39, we wouldn't be here today. They're the ones that have really pioneered JavaScript to bring it to where it is as modern as it is today and as big as it is because of the changes that they continue to push out in the language. So the first thing we're going to jump into is ES6 modules. So modules allow you to load your code asynchronously, and it provides a layer of abstraction to your code. There's two ways to export from a module. You can have multiple name modules, and you can have single default exports. Here's some examples of these. This is a multiple named export. So let's say we have a function called square. It's just accepting a single value, and we're going to go ahead and square that value. We have another function called add. Again, we're just adding those values. Now, if we export those functions from our bathlib.js and then in our new JavaScript file, we want to use those. How would we use those? Normally, we would just add those. We would somehow include this script. Now, with ES6, we can simply import it. This is probably familiar if you've ever used common JS before ES6 became big. They kind of implemented the same exact syntax for importing modules. So as you can see, we're just importing square and add from mathlib. And then we can console log our square nine and our add four and three, and it works perfectly for us. Another way to do it is single default exports. So with this, you're exporting a single function, and then we can import that function and run it. Very simple. So ES6 tools, there are a ton of tools out there. Mainly transpilers, such as Babel. There are bundlers, such as Webpack, and there are also systems that deviate from that that allow you to use a number of different things. So Babel is one of the JavaScript transpilers that allows you to convert your JavaScript from ES6 into ES5 code. And what this does is it allows it to run in any browser, even older browsers. It gives us the ability to use all the syntactical sugar that ES6 provides us while still having the fallbacks. As I said, Webpack is a bundler. And what it does is it recursively builds a dependency graph for your application, and then selectively includes those areas depending on where you are in the front end of your application. Next, we're going to jump into variable scoping. So everyone's probably familiar with var. You would initialize a variable here, set it to equal to var, and console log it, and you get it. Now, var is function scoped. Now what that means is that if I have a function, it's going to not leak out of that function. But if I have a block, it can leak out of the block. Blocks are specifically the curly brackets that you see. Now, sometimes that comes after an if statement. Sometimes it comes for a loop. But it's not necessary. A block can literally be drawn out at any point if you just create curly brackets. Now, the two new ones that we have are let and const. And these are block scope. Now, as I said, blocks are specifically the curly brackets themselves. So if right here we have this block, and then we create two variables, let or const, and we try to console log those, we're going to get reference errors. Because we're outside of the block that those were actually referenced in. And that really allows us to keep our code encapsulated where we want it to be and not leak where it shouldn't be leaking. Here's an example of blocks. So as you can see, we don't have an if statement here. We don't have a for loop. We don't have anything. It's just we're starting a new block level each time. Now, we start the first one, then the second, then the third. And if we try to access the third variable outside of the third scope, we're going to get a reference error. And the same thing with second and third. And that's with let. But it's exactly the same with const. Now you're probably wondering, what's the difference between let and const? So const variables can only be assigned once. But they are not immutable. And that's a very common misconception in ES6. You can change the properties of a const variable. You can also, if you actually want to change, or if you want to freeze the object to where you cannot change any properties, you can use object.freeze. And if you want to just be able to stop someone from changing the structure of an object, that's where object seal comes in handy. But one thing to keep in mind, as I said, it can only be instantiated once, but it is not immutable. Variable hoisting. So this is where this kind of gets hairy. Hoisting is a JavaScript mechanism where variables and functions get pulled up to the top of their scope before code execution. That means that you can do this with functions and vars. I can run this function before it actually gets to fine, because as it's doing that in runtime, that function is going to be brought up to the top before it even calls it. Same thing over here. What actually happens with vars is right here, if we do a console log foo bar, we're going to get undefined. And that's because when you instantiate a variable with var, what it's actually doing is it's hoisting it up to the top, and it's setting its value and its type equal to undefined. And then finally, when it gets down to the assignment, that's when it's actually assigning it. But in ES6, you can't do that with classes. You can't do that with let variables, and you can't do that with const. They are hoisted, but they're not initialized yet, unlike vars and functions. So if we were to try to run this, we'd get a type error for our class, because it has not been created yet. We get an error that says that foo is used before it was defined. And that's because that's exactly what happens. And it's the same thing with a const variable as well. So that's something that you want to look out for when you're using ES6. Another thing in ES6 is the temporal dead zone in blocks. So this is our block, just a nif statement. And this is where the temporal dead zone starts. So if we create a function here, or a const variable, equal to a function, and we're console logging thing, now where does thing come from? We don't have it yet. That isn't a problem until you try to run that. But if I actually set thing, then our TDZ ends. We're no longer in the temporal dead zone, and now, if we call it, we're not going to get a reference error. But what should I use? There's var, there's const, there's let. When should I use these things? What are their purposes? So the only difference between const and let is that const makes the contract that no rebinding will happen to the variable. I can create a let variable, and then reassign it as many times as I want. If I create a const variable, I cannot reassign it. I can only change properties on that variable. So there's two trains of thought when to use these types of things. Matias Bynand, he's a VA engineer at Google. He suggests to use const by default, only use let if rebinding is needed. And he personally thinks that var shouldn't be used in ES 2015. And that's my personal belief as well. This is still a very opinionated thing that everybody has their own opinions, and that's absolutely fine. Kyle Simpson, the founder at Getify, he says that you should use var for top-level variables. Use let for localized variables in smaller scope. And you should refactor let to const only after some code has been written. And you're reasonably sure that there isn't any variable reassignment going to be happening. Either one of these are totally valid positions. And as we get further into the ECMA standard, and as it gets further solidified in later years, this will probably be more concrete. But as right now, it's kind of up to you on how you want to treat that. So we're going to talk about iterables and looping. When you use var, you actually leak a global variable to the parent scope. Because as I said, var is function scoped. It's not going to be block scoped. So as we're looping through, we have our var i equals 0. As long as i is less than 10, increase i. And we're going to do a set timeout here. And what do you think is actually going to happen here? We're console logging within our set timeout. We're console logging i. We're going to get the number 10 as 10 times. Why is that? That's not what we wanted. It's because what happens is by the time this set timeout runs, and again, this is just an example. Imagine this is an AJAX request or some other long-running process here. By the time it actually runs this console log after the one second, i is always 10. So this isn't helpful at all for anybody. Now, if we use let in a for loop, it allows us to have the variable scope to that block. So here we have let. It's exactly the same code. We just changed var to let. And what's that going to give us? Exactly what we want. 0, 1, 2, 3, 4, 5, 6, 7, 8, 9. ES6 also gives us a new way to loop over iterables. So what is an iterable? An iterable is anything that you can loop over. It's an array. It's arguments. It's node lists. Now, there's certain ways to iterate over those objects compared to others. But what this gives us is the availability to do four of the iterable. So we have this constant variable, iterable. It's 10, 20, and 30. And if we do for each constant value of iterable and we console log it, we get 10, 20, 30. Now, this is also handy when you want to loop over something like a query selector. So we go ahead and we do a query selector. We get our node list. And we want to loop over that. Now, you can't just loop over that normally. But in ES6, with the four of loop, you absolutely can. Because it's an array-ish type is what a node list is, very similar to arguments in a JavaScript function. You can also loop over strings, because strings are, again, iterable as well. So we loop over foo, and it gives us each letter individually. Next thing we're going to talk about is arrow functions. And if you've ever worked with CoffeeScript, or I believe TypeScript does some similar stuff, this might look similar. They based a lot of the functionalities of ES6 based on other languages that we're trying to take JavaScript further already. So here we have a traditional function expression, add numbers. And that's going to take in num1 and num2. And that's just going to add the two and return them. Now, what arrow functions give us is a more concise function expression. So as you can see here, we remove the function keyword. And we just do an arrow, start the block, close the block. Looks very similar. But arrow functions give us more than that, too. They also have implicit return. So what is an implicit return? This right here is an explicit return. We're specifically saying we're returning this value plus this value. Now, with the implicit return, this minimizes it by two other, you know, we're removing two lines off this function, num1 plus num2. And it already knows that as we're finishing the arrow function like this, it is an implicit return. It knows that that's what we're returning. There's a few more examples of arrow functions. You can do things like, I have no arguments in my arrow function. Bam. Just an open, close parentheses, arrow, implicit return. If you have a single argument, you don't need to wrap it inside of a parentheses. You can just have the single argument listed. And if you have multiple, you go ahead and you throw it into parentheses. And now another thing that arrow functions give us is it makes it to where you don't have to do any of this bind or this or that equals this or self equals this. So it picks up this value from its surrounding. So take this example here. We have a function, a person object, and this dot age equals zero, set interval, and we're increasing the age. But right here, this refers to the window. And that's not at all what we want. We want it to refer to the person object. So back in the day, we might do this, var that equals this. And now we can do that plus age, plus plus. And yeah, that works. But it's not ideal. So let's dive in a little bit further. We use an arrow function, and this we're properly referring to the person object now. And we don't have to use any bind, that, or self. When should I use arrow functions, though? It's not always appropriate. Take this example, for instance. We have a button that's equal to our query selector of my button. And then we're adding an event listener for click. And then we're doing this.classlist.toggle. And that looks right, but this is referring to the window because we're not within a scope that tells us what our this is. So if it's going to pick up its this based on its surroundings, there's nothing that tells it what it should be. So of course, it's going to be the window. So for an example like this, it's not even proper to use an arrow function. You would just use a regular function here. That way, the value of this would be your button that you're calling your event on. Another awesome thing that ES6 gives us is default arguments in JavaScript. So here we have a basic function. We're going to calculate the total based on the subtotal, the tax rate, and the shipping charge. So we're just returning subtotal plus shipping plus subtotal times tax. And if we go ahead and rerun that, we get our value. But let's go ahead and add some default into the argument. So this is the old way of doing it. If tax equals equals equals undefined, set the tax. If shipping's undefined, go and set the shipping. But we just added like five, six lines to our function here, and that's not ideal. So this is a little bit better. This is still without using ES6. We're just cleaning it up a little bit. Still better, but not the best. Now here we go. It is, now we're back to the same line length that we had when we had no defaults, but we have our defaults in there. So we know they're always going to be set, even if they're not passed in. But what if I only wanted to pass in the first and the third arguments? Can I just do this? Nope, syntax error. What you're going to want to pass in is undefined. So if you pass in undefined as tax or as shipping, it's going to know, OK, this is undefined. So set it to the default. And same thing if you were to just leave off the last one. If you wanted to actually just leave it off, then that's fine too. If you only passed in 100, the other two would straight default. But if you needed to have it to where it's split in a middle argument somewhere needed to be empty, that's exactly how to define that. The next topic we're going to be discussing is destructuring. So here we have a person object. Kevin Langley, my location is Beverly Hills, Florida. And let's create some variables from that object. So let's create a first, and that's equal to person.first. Let's create a last variable. That's equal to person.last. But with destructuring, we can actually do this. Put it in curly brackets and just say first comma last equals person. And that's going to pull the variables or the properties out of this object that are equal to first and equal to last and set them to those variables. Now we can use those anywhere in our application. That comes in handy a lot. And it also comes in handy with nested properties as well. And you can also rename the variables of a destructured object. So you're not stuck just with the keys that the object gives you. Say I want my variable to actually be fname and lname. But they're going to come from first and from last inside of our object. And same thing here instead of city. A city is the key, but we're going to be naming it location city in our application and location state. And those would be the variable names that we would use throughout the rest of our application as we go on there. So what if I try to destruct your property that doesn't exist yet? So here, an example would be you have a settings object. And we have a color property and a height property. And we're trying to destructure that into the width, height, and color. But we don't have any width property here. So what would that do? That's going to give us an undefined. And that's absolutely fine if that's what you're looking for. But another thing you could do, very similar to the default arguments in a function, you can actually set defaults in your destructuring even. And this cleans up your code so much. So now, if we were to destructure this, width would automatically be equal to 2, because it knows that we haven't passed one in inside of our settings variable. And as you can see, our values have overwritten the defaults here for height and for color. You can destructure arrays as well. And this is nice when you get data coming back from either an API or some other form where it's an array. And it's not really in a clean way where you have the keys and you know what they're linking up to there. But if you know that it's in a specific order, you can go ahead and destructure it. First last website equals details. And that's going to pull in those values exactly like what we would think. So the next topic is we're going to have to dive a little bit in, because spread and rest are amazing and awesome as hell, but can get a little confusing. So before ES6, we would want to run apply to pass in an array of arguments. So let's say we had a function called doSomething. And it takes in an x, y, and z. And we're just console logging. We have a variable here, args. And that's 0, 1, 2. And in order to call this function and pass in these arguments as single arguments here and not a z array we have, normally we'd run apply. But then we have to specify we want null for our this value and our args are going to split up there. And that works. But another way to do it is with the spread operator. So what the spread operator does is almost exactly like what it sounds like. It's going to take this array here and it's going to spread it out to where doSomething is actually 0, 1, and 2. And this is very useful in a number of ways. So you can use a spread operator to combine arrays. Let's say I had two different arrays. And they has one, two, and three, and four, and five. In our array one we could push the spread of array two. And what that does is it adds all the items from array two to our array. And we can also do the same thing. We can unshift it and add those items to the beginning of the array. Or we can also combine arrays at any point that we want to. So let's say our array one is actually equal to two and three, and array two is equal to one. And then we put in the array one. And we spread that out. That is what our value is going to be one, two, three, four, five. It specifically spreads out those values at any point that you want to. And that allows you to just have a ton of control over your arrays. If you need to insert things at a certain area after something else, you just have full control over whatever you want to do with those without having to loop over them, check values here and there. You can also use a spread operator to create a copy of an array. So we know that if we just took array one equals array two, it's going to keep a reference to that. It's not just creating a new array there. So what we can do is we can actually spread array one into a new array. And now, if we push four onto our array two, we have two different arrays. They're not keeping a reference to each other. And you're not going to run into problems where you need a copy and you need to adjust that one copy, but keep the reference to the original. You can also use a spread operator with destructuring, which is amazing. So here's an example. We have players, Kevin, Bobby, Nicole, Naomi, Jim, Sherry. So let's say we want to get, this is the order that they placed. And most of the time, you care mostly about the first, second, and third place. So you can place those places. And the rest of them are just going to go into unplaced. So what that does is that's going to make Kevin first, Bobby second, Nicole third. And unplaced is going to be all the rest of them there. And you can use it with destructuring objects as well. So here, we have x, y, and then just put the rest into z. And as you can see, we have one for x, two for y, and z is a to a is three, and b is four. And you can use a spread operator to expand a node list. So if I just try to loop over document.query selector all, it's not going to let us loop over it because it's not an array. It is an array-like item, but it is not an actual array. But if we throw that into a spread operator and throw it into an array here, now, I didn't have an example here because I don't have any divs on the page, but it would list all of your divs. So the other operator here is the rest operator. And the rest operator is almost the exact opposite. The rest operator allows us to more easily handle a variable number of function parameters. So let's say we have a function do math, and we're taking in an operator, and we're taking in a set of numbers. As you can see, it can be any length. We could add 4, 5, 6, 7, 8, 9, 10, all the way up, whatever numbers that we want to, and no matter what, the second variable will always be an array of all the other variables passed into this function. And that makes it really easy because if you have a number of arguments, but you don't know exactly how many you're going to need, or you don't know ahead of time, you don't want to plan that ahead of time, you want it to be able to be variable, this allows it to be really clean code, but still full flexibility there. So there's some new enhancements with strings as well in ES6, specifically template literals. So we've all seen this. You go ahead and you close off your quote, dollar sign, variable dollar, I'm sorry, not dollar sign, addition sign, and then start your quotes again. And yeah, that works, but am I the only one that's ever forgotten a single quote or something like that, and realize, oh man, it's not going to work, OK. Well, now we have template literals. And what we're using here, that's a back tick. It is not a quote, it's a back tick. And within anything that's back ticked, you can do a dollar sign, curly bracket, and then any expression, it doesn't have to be just variables here. You could literally use any expression in JavaScript. So as an example, you can evaluate any expression. We have a price, a tax, and then our total is equal to a string that says the total price is, and then we're actually evaluating this in our string. And it's going to evaluate that on the fly and tell us that our price is this. Now, obviously, you'd want to shorten that down to two digits. This is a quick example. And it also allows you to very easily create multi-line shrinks. So normally, if we wanted to text across two lines, let's throw a slash in in there, and that's fun. But with ES6, you literally just put a new line in there, and you're done. You don't have to think of anything else. It maintains your multi-lines perfectly with no problem. So we also have new functions with strings. So we can check if something starts with. And we can also check if it starts with based on an index. So here, we're saying, does this string start with deeply starting at index 17? Index 17? Deeply. Yes, it does. There's also ends with. Exactly the same. So ends with, if we don't pass anything other than the string, it's just looking for the last bit there. If you pass in with an index, it's going to start. Starting from the right, it's going to go back 16. And then that's where it ends. We also have includes. And we can just ask, does this string include JavaScript? But one thing to keep in mind is that this is case-sensitive. So our string contains a capital S in JavaScript, but this doesn't. So if we're looking for this, it's going to tell us that it's false because JavaScript with the lowercase s does not exist in there. And we also have repeat. And you can just string repeat. If you do a 2.5, it's going to convert that to an int. If you try to do a negative number, it's going to tell you that's a range error if you fail there. And the next topic is enhanced object literals. So let's say we have some variables here. First, last, and age. And we want to assign those variables to properties of an object. So we create an object person. And we say first is first. Last is last. Age is age. This gets repetitive, especially if you have a really big object with a number of properties. Let's shorten that. Bam. We got first, last, age. You don't even need the keys. But let's say you wanted to rename them. You could. Actually, this part should not say. The example here I was trying to explain was that this could be like this. And you could have two that actually are named keys, and one that is an object literal there. So I'll fix that slide. Sorry about that. And you also can use a shorter syntax for method definitions on object initializers. So this is an object. And we would normally start our functions here. Do a comma, new functions. But now, we don't even need that function keyword. We literally just get rid of the colon as well as the function word. And now we can just start it off with parentheses and then our curly brackets. And it's really just nice shorter syntax that just makes it cleaner to work with. Cleaner to read day in, day in, day out. We can also define keys that evaluate on runtime inside of object literals. So we can create an object. And actually, in our key for that object, for each property, we're evaluating at runtime. And as you can see, it's going to give us foo1 is equal to 1. And then as it increases it, foo2. But again, this is kind of, let's clean that up a little bit. Throw some ES6 syntax in there, looking a little better. There's also some new ray features. So we have a ray from. Let's say we have a variable called headers. And it's equal to query selector for all h1s in our application. And we're going to go ahead and get the titles by mapping all those headers and just getting the text content. Now, as you can see, we're using arrow function here, single argument. So we don't even have to have the quotes around it. And we're using the implicit return here for the text content. And that's going to give us a list of all of our h1s text contents. But wait a minute. Heders.map is not a function. And why is that? Because as I said earlier, document, query selector, all. That's going to return a node list, which, again, is array-like, but it is not an array. It has some of the properties of an array, but the prototypal inheritance is not the same. There's a ton of functions, such as map, that is not going to be on their map, reduce, filter, a ton of them. But now, if we can go ahead and we can do it with the spread operator, as I showed earlier. But that's nice, but it's not the easiest to read. So the new feature is array from. And that just really takes something that is an iterable that is not an actual array, but it is array-like and turns it into an actual array. It gives it all the same properties of an array. And you're not actually mucking up the prototype. It's actually totally clean there. You're just transforming it into a new array. And now you have Heders array and loop through that as you need to. So let's clean that up a little bit. We can actually just put this all in one line. So instead of having to do our map on a second line, we can actually put in, as the second parameter of array from, is a map. So we have our call back here, h1, and then going in and passing back the text content. Cleans it up a little bit, but can we do more? Yes, we can. So we just go ahead and throw it all into one single thing, but we could even make this shorter. Implicit returns. Did I even do it? Looks like I have an extra slide here. Yes? Which one? Right here? One more? It will not. It does not retain a reference. It is just, yeah, yeah. It's essentially creating an array from this array-like object, but it's really just allowing you to access those values. And really, once you get titles, all it's going to be is an array of all the content of those h1s. Exactly, not a reference. Absolutely. So here's a very simple, breaks it down a lot. This could be brought even smaller by bringing this document query selector all instead of headers here. The next feature is array of. So array of is very simple. It essentially just takes in values and creates an array of these values. It would be the same as we could take array of and just change that to just a square bracket and a square bracket. And it would literally be the same array. Another new feature of arrays is find. So we have our variable posts. And let's say this is a very simplified version because there's not a whole lot of room on the screen. So we have an ID and we have a title. And let's say we want to somehow get this object out of this array. So we can't do post.to because there's no key here for our array. We can't do that because, again, there's no key. What we can do is we can do post.find. And what find is going to do is it takes in a function that can go ahead and you return true or false based on whether or not the one that you're evaluating is the one that you're looking for. So it's going to loop over every single post and give us post. And then with that, we're going to check the ID and see if it's equal to two. And then assign that to our post variable there. And that gives us learn JavaScript deeply. Filter, you're actually, correct me if I'm wrong, you would be modifying the array. Here we're not modifying the array of posts. We're specifically finding that. Whereas filter, it's actually going to take your array and you're going to say, OK, post is now equal to whatever this comes back at. So if it comes back as number two, now you're only going to have a reference to the second one and not the entire array itself. And it also has find index, which all we changed here was literally change find to find index. And we're still doing the exact same thing. And that's going to tell us, console.post, it's at the first index because as we know, arrays are a zero-based index. The next topic is promises. Oh, this one is a little hard because I will say this is the longest one of my examples. So I needed to create the code space to be huge. And it looks like it's getting cut off a little bit over here. So just bear with me. So we have a post promise. And we're just fetching. Fetch is very similar to dollar sign get JSON, dollar sign Ajax, but it's built in into the browser itself. You don't have to have any type of library for this at all. It's already built in. So we're just going to fetch the JSON API of WordCamp Miami. And we're going to console log that. What's that going to give us? We're expecting all the posts. But it's going to tell us, no, this is a promise. And it's still pending. And now value is still undefined. So what do we need to do with that? Let's bring it back to just the call here. And we're going to add on postspromise.then. So essentially, then is almost like a callback on a click method or something like that. You essentially say, OK, once this completes this fetch, we want to then do this. And it's going to take in the data. We're going to console log the data. And what does that give us? That gives us the response object. So we're on the right track. But we're not there just yet. So it tells us the type, URL, redirection status. There's headers in there. There's the body in there. But it's not really discernible yet. JavaScript, if your application doesn't know what type of data you're really trying to get back yet, it just has this data. So we're going to tell it, OK, run the .json method on that response body. And that is specific to the response object in JavaScript. And we're going to actually chain it then onto that as well, because what this is going to return us is another promise. So then we're going to do another one. And pass in data, which is going to be the data that's coming back from this data.json. And we're going to console log that finally. And now we actually get our posts. Obviously, there's a lot more data to a post, but this is, for example, purposes. There's not much room on the screen. We can clean that up a little bit by dropping each of our then onto another line. And that's exactly the same as it was before. It really just makes it cleaner and easier to read. But if we were to actually just change this, say we took out the A in camp, and now we're getting 404s, because that URL doesn't exist, it's going to give us an error. And it doesn't know how to actually catch that error. So what we need to add is a dot catch. After all of our dot thens, we add a dot catch. And that's going to catch an error. And we're just going to do a console.error on that error. So if we change this to 2019. They're not planning for 2019 yet. We're still having this one. Failed the fetch. OK, that makes sense. And since we have the catch, it's actually going to catch it. If we didn't have this, it would say that it's an uncaught error in the promise. So let's take a look at building our own promises. So promise is just an object that takes in a resolve. It has a resolve and a reject method. And all you're going to do inside this promise, you're going to do all your logic, everything you want to do. And then eventually, you will either resolve your promise and pass the data back, or you will reject your promise. So this is very simple. You can just call resolve immediately. And it will resolve immediately. If you reject it immediately, it will reject it immediately. And what that means is, back here, if we reject, that's also where it's going to come to the catch. Then only happens if it does a resolve. So then only runs if it hits resolve. Catch only runs if it hits reject. So let's say we resolve it with just a string here. And we're doing p.then, you can't see the p, p.then data console log data. So that's actually going to give us our value back there. If we reject with an error object here, and we're not catching anything, we're just using the then. It's going to say uncaught in promise, error, uh-oh. So then we add our dot catch. Please remember that there is a p here. You can't see it because of the screen. And we are catching our error and console error in that. And now you're not getting that uncaught in promise. It is catching the error, and it's not going to stop your execution. Next topic is classes. So here we have an animal class. There's two different ways to declare classes. You can do class declaration or class expression. Class declaration is literally just class, animal, and then curly bracket, curly bracket. A class expression is you're saying const animal equals like class, and then curly brackets. It's just a little different syntax, no difference there in what it does. It's just kind of up to you on how you want to do that. So let's say we have a class called animal. And we're going to add a constructor here that takes in a name. And we're going to set that to this dot name equals the name that's being passed in. And we're going to have a method on here called speak. And speak is just going to console log. This name makes a noise. Because we don't know what type of animal this is. It just makes a noise right now. Let's say we have a dog that extends animal. And I'll tell you, this really came in handy when I used to be a web developer out of that tech office. So we have a dog that extends animal. And in our speak method here, we're going to console log this dot name, barks, because that's what dogs do. So now we create a puppy called spot and spot barks. And as you can see, we don't have a constructor here because it's going to inherit the constructor of our parent class. But let's say, what if we wanted to have another option in our constructor? What if the dog actually accepted name and the breed? Does this work? No, this is going to fail because we're running the constructor, but we're not calling the parent constructor at all. So you've got to make sure that you call the super and pass in the same arguments that it's expecting for the parent class there. And now we could even check dog. We could say, OK, what type of breed is spot? And we'll be able to see the breed. But if an animal was instantiated, they wouldn't have a breed because they're just an animal. And the next topic is async and await. And this is actually the last topic of the talk. So async and await allow us to, when JavaScript's running and you run a function and directly after that function, you're having it do something else, it doesn't stop and finish this first one before it goes on to the next one. It's just going to keep chomping through as it goes. So if you actually wanted to wait for some data or anything like that, you have to explicitly do that. So here we have a function called resolve after time. I wish there was a way to scoot that over some. So essentially, all it is is taking in a variable time. And we're returning a new promise. And we're going to resolve it with set time out according to the time that's passed in. And that's where we're going to resolve it, resolved after time milliseconds. Now, if we do a console log, start resolve after. And then we do a result equals resolve after 500 milliseconds. And then we do a console log of our result there. And then we console log ending resolve after. What we're going to get is we're going to get starting resolve after, or starting resolve after. And the promise is pending. That's what the result is there. And then we're going to get ending resolve after. That's not what we want. We want our value to come back here. So what do we do? Now, we can add async and we can add a wait here. And what that does is it's telling our function here that this is an asynchronous function. And when we're calling that asynchronous function, we're going to await for the value. So before it goes on to the next line, before it console logs that result, we want it to await when resolve after finishes, and then assign it, and then console log it. But wait. Await is only valid in an async function. It's not valid at the top level scope. As you see, this is not, and it's probably easier to see if you can see the whole screen, but this is not within its own function here. This is just top level code with nothing above it. And then there's just one function here. So what we would have to do is we would have to wrap this. This is async function, async call. And this function is the awaited function, or is the just the regular function. So this is our async function. We're going to start the asynchronous call. Then we're going to await our resolve after, get the result, and as you can see, start async call, resolve after 500 milliseconds. You can even see the difference in the time there, the 500 milliseconds that have passed, and then ending async call afterwards. So it's not hitting this one before the value actually comes back to us. We have the value back to us now. Before we actually move on from this line, we already have the value. And you can await as many function calls as you want to. I can await resolve after 500. Await resolve after 5,000. So as you can see, it is waiting five seconds there. It's waiting a half a second there. And it's resolving in the correct order here. So while this talk has been long, there's a number of things that we have not covered here today. There's things in ES6 that we have not even touched on, generators, symbols, proxies, sets and weak sets, maps and weak maps, and even more that's still in review by the TC39 right now. And honestly, it is impossible to include everything that's in here because of the fact that it is ever changing. JavaScript is going to be continuing to change for years to come. And we need to make sure that we stay up to date as well as we can. Most of these functions here or most of these features here that we have not gone over, I will admit are features that I have barely touched myself. So I find that every feature that I did discuss is the bulk of what you're going to need out of ES6 in order to learn the later things today and just continue on with your JavaScript knowledge. Now what I would recommend, if you are interested in learning more about ES6, I would recommend Westboss's ES6 for everyone course. Unfortunately, he just had a sale that ended where it was like $40, $50 off of the normal price. But this course right here is incredible. This is the course that I took in order to get caught up today on ES6. And it is pretty much the only course I took on ES6 because it's incredible. It's an amazingly well done course with a ton of examples, a ton of real world code examples that are not the foobar-baz stuff that some of the slides I have had been. Yeah, continue on with that. He also has a React for Beginners course, as well as a number of other courses. And I would highly recommend that. Thank you for your time.