 So people are still coming in, but feel free to come in. Yeah, hope you're in the right place. This is JavaScript ES6, the best vanilla you've ever tasted. I am Ryan Hagerty. You can see me right there. You can also see me up on the stage standing in front of you. I'm a front-end developer, and I work for a pretty cool company called Chromatic. We're a completely distributed company. We're all over. We've got people in Colorado, Florida, Pennsylvania. I'm in the beautiful Appalachian Mountains of West Virginia. We mainly do Drupal work, but we do all sorts of design, development, deployment work. So check us out, Chromatic HQ. Follow some Twitter. You can find me on the interwebs at HotPizzas. That's my Twitter handle, and I have a pin tweet up there right now with a link to the demo. A repo that has all the code, all the slides, everything you need to get rocking and rolling with ES6. You don't have to set anything up, so check it out. So let's go over kind of like what we're going to talk about. We're going to do a little bit of an intro. We're going to check out kind of the history of JavaScript releases. We're going to cover ES7 before we even touch ES6. There's a reason. We're going to ask ourselves, why even use ES6? We're going to touch on jQuery, Babbel, and then we're going to dive into what you're actually here for, and all sorts of cool stuff about ES6 and how it'll make your life easier with constant let, scope, default and rest parameters, arrow functions, implicit returns, promises, classes, temperate literals, destructuring, and the awesomeness of JavaScript modules. So first off, what is ES6? ES6 is a JavaScript specification. Specifically, it's called ECMAScript 2015. Now you can go ahead and call it ES6 whenever you're talking about it, but this is kind of like its official name, and to give kind of like an evolution of JavaScript and where we've come from. So back in 1997, I was officially originally called ECMA 262, and it started in 1997, and then we have some really good yearly releases. 98, ES2, 99, ES3, and then we have a huge gap, and an ES4 was actually abandoned due to political differences concerning the language complexity, and then we have ES5 and ES6, which is what we're here to talk about. And this is a quote from one of the ECMAScript project editors, and he says, in a very real sense the completion of the sixth edition is the culmination of a 15-year effort. So the future, all right, where are we going? And the cool thing about the sixth edition is that it provides the foundation for regular incremental language and library enhancements. So what does that mean? That means yearly updates, which is pretty cool. So you're going to have every year some new features in JavaScript that are going to make your life better. So I mentioned how we're going to talk about ES7 first, so let's go ahead and check that out. So we have a couple things here. We have array.prototypes includes those originally called contains, but mood tools had a contains method, so in order to not break the web, they called it includes. And it's pretty straightforward. It just checks to see if you have something in an array. So we have one, two, three. Does it include one? True. One, two, three. Does it include four? False. We have a new exponent operator, basically replacing math.power. So three times times two is three to second power. We're going to get nine. And guess what? You did it. You've already learned ES7, which is a cool thing about yearly updates. So there's a ton of stuff in that 15-year gap in ES6, but if you get that and grasp that going forward, these yearly updates are going to be pretty straightforward to grasp and move forward with. So that's cool. But why? Why should I care about ES6? What is it going to do to make my life better? And it basically solves problems. And when you're dealing with large code bases, my opinion is that better than the purest function, better than the most elegant written code, code that is easy to read, understand, and maintain for you, yourself, and others, is more important. And ES6 solves a lot of those problems. We're having an ES5 with this. So some of the ways that it solves this is through scope, promises, this keyword, modules, parameters, classes, and more. And another reason ES6 is awesome is because it's a web standard, right? So it reflects best practices. It's been standardized. It's been through the ringer. You know it's going to be around forever because it's a web standard, so you know anything you write in it is going to work for a super long time. It's not the trendy hipster framework of the week. You know it's going to be around forever. And it's not Drupal specific. It's not WordPress specific. It's JavaScript. You can use it anywhere on the web. And that takes us to my jQuery, right? So what about jQuery in the world of ES6? And I want to say that, you know, I love jQuery, right? I'm not going to bash jQuery. jQuery is actually awesome. But I do want to contrast each of them, all right? So kind of give you like a little bit more perspective about, you know, whether or not you want to use one or the other, or even both. And ES6 and jQuery, well, they solve different problems, okay? So if you still need to support significantly older browsers, then jQuery is probably the best answer for you. If you have a super low budget site, and you're not familiar with ES6 and you need to get rocking and rolling and doing work, then jQuery is probably the best solution for you. But I do want to highlight on performance, okay? So there's a lot of big performance wins, like Source Set, okay, to give you responsive images to save you a lot of bytes down the wire. But performance is actually really great performance sites. They're actually the culmination of a bunch of tiny wins that kind of culminate into a super-performance awesome site. And the current size of jQuery 3.11 is over 90 kilobytes. So getting rid of jQuery is one way you can kind of take those small steps in having a super-performance site. And I actually went into my cache, and I saw that I had 21 different versions of jQuery in my cache. And that's just different versions. That's not versions hosted on one CDN versus another CDN versus self-hosted versions. That's just different kind of just versions of jQuery. And also when you use ES6, you're gonna have a better understanding of JavaScript. It's not an abstracted framework or library. It's JavaScript itself. And there's lots of native solutions that we've been using in jQuery for actually around for a long time. All of these have native solutions. Add class, has class, find attribute, toggle class, map. So in conclusion, probably use ES6, maybe. I know it's super hard to stop, but at the very least, I'm not telling you not to use jQuery, but at the very least, now we have to ask ourselves, should I use jQuery? Is there a justified decision for me, too? Go ahead and use it. But now, instead of saying, oh, man, thank God it's making Internet Explorer work, we should ask ourselves, should we actually use it? So let's get started, all right? Let's get started with ES6. Now you can ask yourself, well, I have some older browsers that have to support. Can I use it? And there's a site called Babble, which we're gonna talk about in depth here in a little bit, and they have a compatibility table which shows you all of the kind of features of ES6 and which browsers support them and how well they support them. You can use caniuse.com to look up specific functions. Here I'm using arrow functions, we're kind of like foundational of ES6, and you'll notice that like IE11 doesn't support it at all, and I don't know any website that, you know, can drop IE11 at this point. So the solution of that is Babble. All right? So what's a Babble? A Babble is a compiler that will transform ES6 into legacy browser ES5 code. Yes, even IE9. You can write ES6 and it'll work in IE9, which is pretty awesome. And here's an example from Babble's own website, and they can have like a little demo area for you to try yourself to see how it actually works. When you write ES6 code, and here we actually have an implicit return, an arrow function, and that exponent operator that we talked about, and we're going to go over these. But all it does is turn that arrow function into a regular function, an implicit return into a return, and that exponent operator into math.power. So that's pretty cool. And to get started with Babble, you need to use npm or yarn. I prefer yarn, but in the demo repo I use npm. I feel like more people are familiar with it. You'll need to use some type of task runner, like gulp, grunt, webpack, or if you don't even want to use a task runner, you don't even have to. There's a command line interface that Babble provides, so you don't even have to deal with that. So let's go over battle CLI really quick. So in my package.json, I have a little script here, right? Saying, alright, so when I run battle CLI, I want it to look in a node module's Babble directory. Look in the source folder, and in the out directory, put it in the disk folder. Okay, so let's check out what I have in my source folder. I have an example of an implicit return using the arrow function. And then in my command line, I just say npm run battle CLI, and it's done. That's all you gotta do. And then I have ES5 code written in ES6. And here's the compiled code. Arrow function converted. I have a return in there, awesome. But what I did in the demo repo is I used gulp. I feel like a lot of people are familiar with gulp. If you're not familiar with gulp, don't worry about it. Demo repo's got it set up for you. But this talk isn't about gulp, so I'm just gonna touch on it briefly. So I installed some packages here, gulp, gulp babble, babble preset ES215, 2015. And in my gulp file, I have a really simple task here called js, where the source folder is my JavaScript source folder, any file called JavaScript, piping babble through there, and the destination folder is JavaScript. This is js. So if I type gulp, boom, done. Pretty awesome, I got ES6 code. Now you may be asking yourself, all right, if this compiles in a different code, how do I debug this, right? That could be a problem. And the answer is source maps. Okay? So if you use source maps, you have your compiled code here, right? And the browser is running aggregated code, but that source map will help you find the original file that a particular piece of code comes from. So I have a source map here. You can see the original code I wrote. Pretty cool. So now that we got it set up and running, we've been able to history all that cool stuff, let's check out some real ES6. Okay. const n let, what some people are calling the new var. All right, so var has some problems, okay? You can update it. Here are the var dc, Drupalcon. I can say dc equals Drupalcon. When I log that dc, I'm going to get Drupalcon. You can even redefine it, all right? I have dc equals Drupalcon, dc var dc equals Drupalcon. If I log that dc, I'm going to get Drupalcon, all right? And that's kind of gross. I feel like it's gross, because if you have a giant file and with a huge scope, you may not necessarily know that something is redefining it or re-updating it down the line. So kind of going back to how it makes our lives easier by having cleaner, more readable, more maintainable code, const n let kind of solve this. With let, like var, you can update it. So let number equals 41, number equals 42. I'm going to get 42. But I can't redefine it. If I redefine the number, console log that, I'm going to get identifier number has already been declared. Let is really good for loops, right? So here I have this example loop, right? So I have var i equals zero, simple loop, and I have a set timeout, right? When I log that instead of that set timeout, I'm going to get log, I'm going to have five, five times in a row. Why is that? It's because the loops already run before that set timeout happens. But if I have let, I'm going to get what do I expect? Zero, one, two, three, four. Why is that? Well, that can be updated and, most importantly, const n let use block scope. And block scope are these little curly brackets right here. And we're going to talk about scope right after const. So just keep that in mind, these curly brackets right here. With const, you can't update it, right? So I have name ryan, name equals rai. I'm going to get an error, assignment constant variable. I can't even redefine it. const name, const name, ryan, and rai-rai. Identifier name has already been declared, like redefining let. And this is super helpful because, like I was talking about with var, when you see a const, you're signaling to yourself and other developers that this is always going to be the same within this scope. So you don't have to worry about it, like, ever changing. You know what it's going to be, which is pretty cool. But I do want to point out that const is not immutable. Right here I have an object named person with a property of name. The const of person can't be updated or redefined, but the property can't. So I can say person.name equals rai-rai, updating that from ryan. I'm going to get rai-rai, no errors. So const versus let, what should you use? And I think you should use const. Like I said before, when you use const, you're signaling to other developers that this is staying the same, makes it easier to read, easier to maintain, you don't have to worry about it. So I would use const. And that takes us to the next section, which is scope. So what's the new scope in ES6? This is all you got to know. These curly brackets right here defines a new scope. So when I have name equals rai-rai, and I log that, I'm going to get rai-rai. It's not going to give an error about redefining or updating or reassigning. If I log it outside of this scope, I'm going to have the name up here, const log name equals ryan. Now let's talk about default and rest parameters. So to check out a default parameter, this is another example to allow you to write cleaner readable code. Default. All right, here's a simple example. I have a simple function here. Log favor food. And in this parameter, I'm saying food equals pizza. And all I'm doing is console logging that food. Log favor food. If I don't pass anything into it, the default parameter is going to kick in. It's going to give me pizza. The log favor food is beer food. Pizza is not going to show up at all. Default parameter is beer food. And here is another example. Kind of a more real world example. If I want to change the body color, basically I'm saying, hey, the background color applies style onto the body of whatever the color is. But here I'm saying the default parameter is dodger blue. I don't pass anything in. The body color is going to be dodger blue. I pass something in. It's going to be whatever I pass in. This light gray right here. So let's talk about rest parameters. All right, rest parameters allow you to pass in an unspecified amount of parameters. And this is... The way you do this is through these little ellipses here in the parameter. And in ES6, these parameters are actually... these rest parameters are actually an array, which is how I'm checking length here. So when I console log numbers that length, I'm checking that array. So if I just pass in 1, I get 1. Log numbers, 1, 2, 3, 4. 4. Sweet. And that takes us to my, one of my favorite things, arrow functions. All right, arrow functions are super cool. And let's kind of check out why arrow functions are awesome. So in ES5, you know, this is pretty straightforward. You know, we just have a function, pass in a name. We're going to log that name. Log name Ryan. We're going to get Ryan. Arrow function, all we're doing is removing that function name. We're putting parameter right here, and we're using what is called a fat arrow equals greater sign. And it's the same thing. That's arrow functions. So what's the big deal with that? What makes it so cool? All right, and what makes it so cool is actually how it handles this, the context of this. And what it does is that it lexically binds this. Now, I remember when I first got started, like, I used to hate this keyword. It was so confusing to me. I was like, what is it actually referring to? The context just kept changing. It's probably because I didn't really have a good understanding of scope. But, you know, blessings go on to new developers now because they don't even have to worry about that. So let's check out an example of how lexically binding this will make your life easier. Okay. So I have some code here. I have this object. I have this listen click, right? And it's looking for an element with an ID of a button. It's adding a click event listener. And it's running this.logclick. And logclick just says, hey, anytime someone clicks this, logclick. Okay. And the important part about this is how I'm using function here. All right? If I do this right now, it's not going to work. Now, I know we could just get rid of that function and do this, all right? But I invite you to suspend disbelief for the sake of this demo because this is the important part. This kind of like creating a new scope here, right? So if I do this, it's going to say this.logclick is not a function. All right? Now, there's a couple of ways we could get on and get around this. I used to do this all the time. I used to do const that equals this and then inside that.logclick. It's a little shameful, but, you know, it works. You could use call or bind. And that's better because it was specifically made for this type of thing. And you're signalling to other developers. You know explicitly what you're doing with the context of this. So that's great. That's a cool thing with arrow functions. You don't have to worry about that, right? This will work. We have the same kind of setup here, but instead of a regular function, we're using an arrow function, and that's how it lexically binds this. It'll just keep the context of this going down the chain. So we could have arrow function after arrow function after arrow function, and it's going to still lexically bind this to its outer scope, whatever the parent of the highest-most parent object is. So sweet. All right, let's check out implicit returns. So I have a simple function here, all right? We're going to be using arrow functions from now on, and all I'm doing is taking a number and timing it by itself. But if I do this, I'm going to get undefined. Why? I'm not actually returning anything. So to kind of fix that problem, all you do is take those curly bracket scopes, get rid of them, problem solved. It's the same code except all I'm doing is getting rid of the curly braces. So I'm timing it by this and not returning anything, but it's an implicit return about those curly braces. So console log number two, we're going to get four. And that takes us to kind of like a bigger section, and that is promises. All right. Now someone could give an entire talk on promises, all right? But I'm not going to go over anti-patterns or kind of like things you can do with promises that kind of like beyond kind of like the higher level thing. What I want to do is kind of touch on the basics and kind of like maybe get you excited about promises and why they're awesome. I feel like when we're dealing with asynchronous code, you know, we have some callbacks. This data is dependent on that data. And then we go, that data is dependent on that data, and we kind of keep going and going and going. And you know, what is colorfully known as callback hell. Now, I'm guilty of this. I think I still have a GitHub repo up with just like this chain of callbacks which is gross as hell. But like, this will actually help and you know, you can separate those functions out and make a little bit of cleaner code but still callback hell because it's difficult to read. It's difficult to understand the flow of asynchronous coding. All right? So what is a promise? And I'm going to tap Kyle Simpson right here. Kyle Simpson is a super awesome JavaScript developer. He's a great teacher. He has tons of free resources online, talks, all that. I highly recommend to check him out. So I couldn't, and his was always better. So I'm using his. And Kyle Simpson describes the idea of a promise like ordering a cheeseburger. So you go to the counter, you order your cheeseburger, pay the money, you get a receipt. That receipt is like a promise. So you go to the counter like you're expecting a promise. Now you can go to the counter and they could be like, oh, here's your burger. That promise has been resolved. So we're out of burgers, so that promise is rejected. A promise is only like a guarantee about a future value. We don't know what that value is yet, but it's a guarantee that something's going to come back. So let's check out a basic promise. We have a new promise here, right? And you'll notice that, like, we have your promise, new promise, resolve, reject. Well, what's that? It's a new handler that is given two functions as parameters. It's typically called resolve and reject. And right here, I'm kind of simulating a call to set time out of one second, and then that promise is going to resolve whatever data I have. So right now it says your data. So what do you do with that? Well, then you have then. And this is how you consume your promise. Okay? So when I have your promise that then, when I have that one second fires, I'm going to resolve that data. Everything works fine. Console log, what did I get plus message? It's going to say, what did I get? Your data. So let's kind of explore this a little bit more. So I have Amazon AWS is true. So let's kind of say we're checking if Amazon AWS is up. A new promise, resolve, reject. Okay? It's true, cool. It's down. So how do we consume that promise? What do we do with that value once it's fulfilled? Well, we use then. We have the same thing. Function, what did I get? Plus message, would I get your data? Function error. Oh, no. The error message, it's down. So all together, Amazon AWS is true. All right? So it's going to go then. Amazon AWS is false. Uh-oh. It's going to reject it. Then we're going to get, oh, no. It's down. And you can even chain your promises, right? So right now we're consuming promises, and now we can actually chain them. So right here, I have resolve, reject. Result equals two. It's going to immediately resolve. It's right here, two. I'm going to take that result. Times it by two, I get four. Times it by two, I'm going to get eight. And this is a good example of how you can take asynchronous code, which might fire, you know, here or there, it's unpredictable, right? And this kind of like makes a little bit more of a linear timeline, a little bit more easier to read and maintain. Because we're saying, hey, our promise has gotten some type of data. It's a guarantee of our value, right? Once we got that data, then do this, then do this, then do that. So it's kind of like makes it more easier to read. And you can even throw an error function here. We can throw a catch. In case one of these thens somehow stops working. So we have an error function, console log here be an error. So instead of returning that new result, we're going to return a promise reject. We're just going to say, hey, reject that promise. That catch is going to run here be an error. You can even do promises that, oh, you can take an array of sites, right? So here I'm just kind of simulating some sites here. Site one, site two, site three. Promises all. I'm going to take those APIs and then for each API, I'm just going to log the API. Site one, site two, site three. And there's a catch to promises all. Because if any one of those sites fails, the whole promise is going to fail. So this could either be good for how you set things up or it could also be an unexpected result. But I felt you all should be aware of that. Let's check out classes. All right. We have classes now. Which is pretty sweet. All right, so we have a basic thing here. Class food. We have a constructor, which initializes the object properties. You know, this is not required in classes in ES6, but going here to show you, for example, we have a method called ascribe. And all I'm doing is console logging. This.name is the best food. So const pizza equals new food. This.name equals pizza. Pizza.scribe, pizza is the best food. How do we do this in ES5? All right, well, we have bar food function, blah, blah, blah. Food.prototype.describe, console log, this name is the pizza food. And down here, we kind of do the same thing. Pizza.scribe, pizza is the best food. But guess what? Classes in ES6 are just syntactic sugar. This code is actually exactly the same under the hood as ES6 classes. So nothing's really changed. It's not just classes, but not really getting kind of like true classes. It's not really a class. So let's kind of check out why it's not a true class. We have some code up here from before. We have our class food. Method describe, const pizza equals new pizza. But guess what? Pizza is not an instance, all right? It's not copying the object properties into a new object, independent of its original. Independent of food. So if I go down here and I change that method of food, even though I have pizza already up here, food.prototype.describe, food is altered. When I do pizza.describe, I'm going to get food is altered. So that's definitely something you should be aware of that we're still following the prototype chain. We're still using prototypical inheritance. It's not a true class, but we're getting there. Kind of looks like one. You can even create subclasses. Food, method of toppings, const mystyle equals new pizza, mystyle.toppings, mushrooms and onions, I like mushrooms, onions on mine. And this little feature called super. And that refers to the class it references. In this case food. So I have super up here in the constructor. So I'm referencing foods this.name, just saying it's pizza. In the toppings method, I'm calling super.describe, so any time I say hey, pizza.toppings, I'm also going to call food.describe. So const mystyle equals new pizza, mystyle.toppings, mushrooms and onions, here's that super.describe, pizza's the best food, and then finally toppings, I like mushrooms and onions on mine. And that's classes. And the next section is template literals. Now template literals are something small, but I think are super awesome. And I hope you do too, because they're really cool. And they're definitely not as complicated. So you know how you do this in ES5, right? You got this like gross like, oh I want to put like a variable in here, so space, quote, plus space, variable, the space, quote, it's just such a pain to write, it's not a good experience. In ES6 we have embedded expressions now. So all I have to do now here is like dollar sign, curly brackets, boom, done. And you'll notice I'm using backticks here. Why am I using backticks all of a sudden? And that's because if we use actual quotes, it's going to be a literal string. We're going to get beverage up here. It's not going to be an expression. So I want to make sure to definitely use backticks, and in fact in all of my code, all my JavaScript code now I use backticks exclusively. I'm pretty sure I'm going to use a template literal somewhere. So why not make your code clean, consistent, and just use backticks everywhere? You can even add a little bit of logic into your PivotLiteral. Right here I have kind of like a little ternary, so let's check out what's going on. I'm looking for this query, a little thing that has a class of next. I'm saying hey, next link, insert a json.atml, run template. So what's template do? Well, here's the ternary. Is pizza true? I'm so sad. So cheer. Hey, pizza's true. Up here. It's going to insert ya. And I'll leave it up to you whether or not you decide you want to put logic in your templates. That's up to you, but I've run into a couple scenarios where it's been super useful, and you know, my feeling is if your decision is justified, then go ahead and do it. And that takes us to destructuring. This is probably my favorite slide on the deck, because destructuring is pretty much the lamest, boring word ever. I have some really exciting balloons happening. So let's get excited about destructuring. Yeah, all right. I like that enthusiasm. All right. So we got some variables here. Bar name one, name two, name three. Imagine if this came from some data, right? It was like a pain. Well, destructuring allows you to extract data from arrays and objects into distinct variables. All right? So what does that mean? We'll have an array here. Name one, name two, name three, and rye and rye and rye rye. Name two. Boom. It's a distinct variable. You can even clean it up a little bit. I'm having this array already declared here. Then name one, name two, name three equals names. Guess what? These are all distinct variables now. I'll log name two. Gonna get rye. You can do this with objects. Okay. I have a superhero of a property of alias and name. Const alias and name equals superhero. Alias is its own constant now. It's gonna log spider-man. You can even nest destructuring. So I have a supervillain here, right? Alias name. And then I have some nested properties here. Weaknesses. So weakness one is water. Weakness two is planning heists. Const alias. And then I have a nested destructuring here. So weakness is gonna be a distinct constant here. If I log alias and weakness, I'm gonna get sandman and water. And that takes us to my favorite section, the most awesome section, which is JavaScript modules. Okay. So we got some problems. All right. You know how like you would have you load your jQuery in a script tag. You load your flex slider. Then you have your flex slider and it's kind of like a global namespace. And then, you know, I'm not been right out of that anymore. Not dealing with it. One minor but valid point is pollution and possible collision in the global namespace. But I want to say one of the biggest things is that there's no dependency management. Many scripts duplicate functionality that could be easily shared across an entire site. So instead of having one monolithic module, what if you wanted to break up pieces of a module into smaller modules? Right? For usability across many different scenarios of your site. And this is what JavaScript modules allow you to do. The problem is, is that browsers don't know what to do with them yet. Chrome doesn't know what to do with them. So we're gonna need some type of package manager. And here's the four most popular I think right now. We got Webpack, BrowserFi, JSPM and Rollup. We have this really cool feature called tree-shaking. And what that'll do is actually look through your JavaScript modules and see if there's anything that's actually not being used. And it will not include that in your actual bundled JavaScript. Super awesome. Way to get a little bit more performance win. But let's check out actual modules. And this is all you really need to know using them, which is import and export. Okay? And import and export are implicitly asynchronous. No code will execute until the requested modules are available and processed. So right here, check this out. Okay. So I'm exporting a constant called color change. I have this method, change color. I'm taking in color and element. And all I'm doing is saying, hey, apply a background color style of color to the element. So how do I use this? This is on a different, well, in a different file. You can import that color change from modules, color change.js, and then I can use it here. Color change, color, dodger blue, document body. It's gonna change the body color to dodger blue. You can import all sorts of modules, right? You can import several into one file. And instead of having, like, actual, like, you know, listing the file name every time, you could have a list, like a JavaScript file that has nothing but a list of all of your modules and import it from there. You can import and import functions. So I'm exporting a function here, console log high, import high from modules high.js. It's gonna log high. You can import classes, objects, primitives, all sorts of cool stuff. And I can't stress enough how awesome JavaScript modules are. It's such a huge win for cleanliness and reusability. And it's really gonna, like, change the way you approach how you develop JavaScript. Because it's gonna, like, reinforce a component level-driven JavaScript. You're gonna start thinking about, okay, so I'm building this, how can I actually will this actually be useful in other parts of the site? How can I actually reuse this in other parts of the site? So it's gonna make your development experience better, and it's gonna make the work you need to get done faster. So your velocity will go up, your experience will be happier. You'll high five other developers. It'll be a great time. And guess what? We did it. That's ES6. I know it was a lot. I went through it, but we did it. It's super cool. All right. So what's next? Well, we already know ES7, so we did that. That's cool. And then ES8 is coming out, and that's gonna have some async wait functions. So the kind of recap, all right, what do we learn? We learned about constant let, about how much cooler it is in BAR. We learned about scope, the curly brackets, we learned about default and rest parameters, we learned about arrow functions, and how they kind of solve this problem. We learned about implicit returns, promises. We have classes now, but they're not true classes. We learned about template literals, how boring of a word destructuring is, and we learned about how awesome modules are. So if you go here, twitter.com slash hot pizzas, pinch wheat, got the repo up, play around with it, send me questions, whatever. If you feel like writing out a longer URL, there's a GitHub link. Same thing. And thank you all. So we have some time for questions. Anyone has questions? Hit me up. Hi. What should happen so we can adopt ES6 in Drupal Core? In Drupal Core? That's a great question. Because it would involve some kind of tooling, I assume. Yeah. You know, I'm not familiar. I'm not actually in the project hues of Drupal Core, so I can't really address that specifically. But I mean, I would guess it would be kind of just one, check the browser support, two, check how intertwined you are with jQuery, what places you can refactor that if you even want to. Including some kind of compiler to run that. You don't even need the compiler. You can just run the compiler code to stick those files in there. But yeah, I think it would be kind of straightforward. Just kind of like refactoring things, really. Okay. Thank you. Yeah, sure. Yeah, all right. Well, thank you all for coming. Yeah. Awesome talk.