8. es2015: syntax
Class sugar: class, extends, super
Arrow functions: arr.map(x => x * x)
Destructuring: var { x, y } = getPoint()
Rest/spread: var [first, …rest] = els; Math.max(...myArray)
Parameter defaults: function parseInt(x, base = 10) { }
Block scoping: { let x = 5; const y = 10; }
9. es2015: data structures
Map: object-to-object O(1) access time
Set: O(1) lookup and storage
WeakMap/WeakSet: private state and branding
Iteration protocol: for-of across anything, even user iterables
10. es2015: game-changers
Generators: lazy sequences and async/await-like syntax
Promises: standardized async; play well with generators
Proxies: virtual objects, no more .get(…)/.set(…, …)!
Template strings: jsx`<a href="${url}">${text}</a>`
Subclassable built-ins: class Elements extends Array { … }
30. async function* directoryEntries(path) {
const dir = await opendir(path);
try {
let entry;
async for (const entry of readdir(dir)) {
yield path.resolve(entry);
}
} finally {
await closedir(dir);
}
}
async iterators
31. <script type="module">
import a from "./a.js";
import { b } from "../b.js";
import $ from "https://cdn.example.com/jquery.js";
</script>
module loading
Some of what we’ll talk about will be review, and some of it will be pretty crazy stuff that you might not follow just from reading a single slide. I’ll be going over a lot, and not spending too much time on each thing. I promise I’ll put everything online after my talk, and you can investigate them in detail. I just want to give a broad overview, from the basics to the most far-out new stuff, so that you know what’s out there and can learn more on your own. Let’s start slow…
The biggest news in JavaScript is that the language has undergone a major revision, with new features being introduced all over the place. I’ll go through these briefly, so you can get my take on what the most important point is about each feature.
So that’s what’s actually in this newest version of the JavaScript language. How does it actually play out when we see it in real projects? It’s still somewhat early, but especially due to Node.js, there have been some trends starting. Here is what I’ve noticed:
This is some code from the jsdom project I work on, which works strictly on the latest version of Node.
const everywhere, or sometimes let; no var
Use standard class syntax
Use arrow functions whenever possible; here my module.exports
Shorthand object literals, of course
Using a symbol to store the private state
ESLint rules to enforce some of these things, including one I didn’t talk about, using template strings instead of concatenation.
The other big trend, of course, is to use promises for all asynchronous code, instead of for example Node.js-style callbacks. You can even go further, and use generators and the “yield” keyword as a sort of “await” substitute. So here I am “awaiting” mkdirp, and execFile, and fs.writeFile, and more.
This code sample is from a small server I wrote which allows you to upload some files and get back a zip file. It uses the koa server framework. It does a lot of I/O, and you can see how the code flows entirely differently with ES15 features than with Node style callbacks. The promise return values are what make this possible. You can check out the full code sample to see how this all works, but the takeaway is that by having your module return promises, and by using tools like koa you can opt in to this much nicer style of code writing.
The final trend, which goes beyond ES15 in many ways, is the extensive use of Babel as a transpiler. It is useful for old browser environments, where if you need to support Internet Explorer you’ll need to transpile down. And it is useful for code that uses nonstandard features. Here I have shown it used for decorators, class properties, and JSX, which are big features. Sometimes people say they will be in ES2016, but that is definitely not true; they are nonstandard.
Babel is good for nonstandard stuff, but if you are just writing standard JavaScript, you might not need it. Node.js has almost everything Babel does, with a few notable exceptions like destructuring and parameter defaults. Neither Babel nor Node.js has proxies. Babel can transpile module syntax, but that is not a good idea, since nobody knows how modules work yet. It is mainly for when you need to support old Internet Explorer versions. (Edge has support for pretty much everything Chrome and Firefox support.)
OK, so enough about the language for now. I know this is a Node conference, but I want to talk a bit about the cool ways that JavaScript is being used on the front-end, because in many ways that is where all the innovation is. The Node.js community and core team is focused a lot on stability and on keeping core small and such, and so there is not a lot of room for innovation in that regard. They are just playing catch up on es15 and such, and working on LTS releases and so on. So the browser is where the cool stuff is happening today, that I want to show off to you.
The foundational reason the browser has so much exciting stuff going on connected to JavaScript is this document, called the “extensible web manifesto.” It’s essentially saying that the browser has too much C++ magic in it, and instead we should explain all the magic so that JavaScript code can do very low-level stuff at every point in the browser stack. We’ll see a bunch of examples of that coming up.
A simple example of the kind of magic that we’re trying to let JavaScript explain is the HTML parser, and how it goes from the tags you write in your HTML files, to elements in the DOM tree. The custom elements API is what makes this possible. This API has been evangelized by the Chrome and Polymer teams for many years, but it’s been effectively a Chrome-only API for a long time. Unfortunately that’s still true right now, but we’re working very hard to come to an agreement on a design that everyone likes. And it’s better than the Chrome version, even.
Service worker is another heavily-evangelized part of the extensible web movement. Not everyone realizes how powerful it is though. It is essentially a JavaScript programmable proxy server embedded between the web page and the internet. As such, you can apply a lot of the usual server-side programming techniques that we are used to from Node.js inside service workers. The library I am showing here, service worker toolbox, makes that very clear, with its Express-like router syntax. You could also imagine a koa-esque framework, which would be pretty cool, so you could write code like I showed earlier. Someone should build that!
The final example I want to show where JavaScript is really getting involved in parts of the browser where it has never before had access is this custom paint API. This is actually one of a set of APIs, called “Houdini,” which seeks to do the same for all parts of CSS. But custom paint is probably the most far along, and also the easiest to explain. The idea here is that…
OK cool. So I hope you guys enjoyed hearing a bit about the cool ways that JavaScript is being used on the front-end, even at a Node.js conference. As I said, maybe Node.js can take some inspiration from the way the web is exposing more and more of itself to JavaScript, and refusing to slow down its API evolution. Anyway, let’s go back to talking about the language. What does the future hold for JavaScript?
Check out this URL. There are two magical things about it.
First, the spec is now on GitHub!
Second, the spec is now a living standard!
The real takeaway from that URL, and indeed from modern standards development in general, is that spec version numbers are bullshit. You should never care about what version a spec is on, or what version a feature is introduced. Who cares? Like we talked about when talking about Babel, and when not to use it, what matters is what’s implemented in your target environment, or in the intersection of all your target environments. Features might change if they’re not implemented in many places, but they’ll be reasonably stable once they see wide implementation.
So with that in mind, I’m not going to tell you about all the wonderful features coming in es16 or es17 or whatever. Instead, I’m going to tell you about some cool features that are coming relatively soon, because implementation has already started, and then some other features you might want to keep an eye out for, but nobody’s started implementing yet.
Already implemented in Edge behind a flag, and Firefox nightly. This is happening! Lots of conference talks about this.
Implemented in Firefox nightly, in development in Chrome and Edge. This is kind of an esoteric feature, but it’s about unlocking the possibilities of your hardware. Note how ugly it is, with the method names instead of nice operators.
And that’s it, basically. There are a couple library functions in the works as well, but otherwise, all the rest of the future stuff I’m talking about is still pretty far out there. Maybe it’s in a transpiler, or maybe it’s not, but it’s unstable and may or may not make it in. That said, here are the things I think are particularly interesting to watch…
One big area of interest is expanding the type system. Not in a static typing SoundScript sense or anything, but in terms of giving us new dynamic types that serve the language better. There are a lot of interesting ideas here, but they all kind of float around this idea of value objects.. ……
Decorators are a feature that are getting a lot of thought from their champions in TC39. Essentially, they let you run a function on top of some syntactic element, and modify it (at runtime) to behave differently, doing code generation for example. In this example, the @performance decorator is wrapping the doImportantComputation() function to output how long it took. It’s actually replacing the original method that you declared with a new one that wraps it.
An area that I’m personally responsible for working on is making promises cancelable. Here is some idea of what it might look like. The thing I am trying to show here is that we have a long promise chain, with lots of thens and a catch and a finally (which is new), and then we cancel the very last promise in the chain. This should be able to cancel any of the intermediate steps, depending on where we are.
Another thing in the asynchronous realm is the idea of async iterators and generators. This is an example of an async function*, and an async for loop, which iterates over a directory, asynchronously yielding the directory entries. You can use await in here, to do async stuff. You can use yield in here, to generate a sequence. And you can use async for, to do async iteration. I think this is a really beautiful primitive for “asynchronous plurals,” and a very important one. Others on the committee are interested in something called “observables,” but those are a lot more awkward than async iterators in a variety of ways. I have another talk about that.
And lastly…. The module loader. So yeah, modules are technically in es15. But nobody can use them, at least in a standard way, because there is no spec for loading them, just for their syntax. There are nonstandard ways of doing this. E.g. Babel or Traceur or TypeScript have their own module loader algorithms, which are not based on a spec and do not map to what will be implemented in engines, but are just made up, or just reuse the Node algorithm, or similar. Well… eventually maybe we’ll get a spec on this stuff. I think pretty much everyone involved knows a few things…
And that’s pretty much it for the state of JavaScript… except… one last thing we should talk about…
What is this web assembly business? Well… we don’t really know yet! The basic idea is to have some kind of second language in the browser VM, alongside JavaScript. It would be a compile target for languages like C++. Or maybe also languages like Java? But there is a lot of speculative talk. In some senses it’s basically just asm.js, but easier to compress and parse? But then, people are talking about adding threads and shared memory to it, maybe? There is a lot of effort going in to making sure it shares the same VM as the JavaScript VM, but how does that work exactly? Can wasm call web APIs? What if they return complex JavaScript objects, like a promise or a Map? I have a lot more questions than answers, but there’s serious implementer resources going toward this second language in our VMs, and it’s worth keeping an eye out. We’ll have to see.
In the end, though, I’m not worried. JavaScript is here to stay, and it’s doing pretty well. Thank you.