The 5 features of ES8 and a wishlist for ES9

As we near the finalization of the proposal, it’s looking like ES8 is going to deliver much more than the simple updates of its ES7 predecessor! We wanted to take a few moments to highlight our 5 favorite things about the upcoming 2017 release.

1. Object.entries and Object.values

When an object is used as a hash filter, you often need to know the values of an object. This standardizes an approach found in most libraries and toolkits.

Similarly, it is often useful for iteration or serialization to have an array of key/value pairs from an object, or its entries. With the ES6 Map constructor accepting an iterable of entries, and its associated entries iterator, this makes it easier to convert a plain object to a Map via passing entries to the Map constructor.Review on Github:Object.values/Object.entries

3. Object.getOwnPropertyDescriptors

ES lacks a method for properly copying properties between two objects. This proposal solves this seemingly simple but complex problem that has been implemented at times in almost every JS toolkit or framework. Currently it is a stumbling block for efficient immutability, true composition of ES Classes, something that would benefit Decorators, and just less surprising in general than Object.assign.Review on Github:Object.getOwnPropertyDescriptors

4. Async functions

The introduction of promises and generators in ES greatly improves how we write asynchronous code by improving the control flow structures parallel to those of generators.

This change is pretty significant and we’re very happy to see this arrive in the language as it was a major missing piece for how we write async code.Review on Github:Async functions

5. Shared memory and atomics

Of the finished ES8 features, this one will probably take the most time for people to understand and leverage. It’s been intentionally implemented in a very minimal manner, with the specification stating “At this time the proposal adds only low-level primitives to ECMAScript; we expect the developer community to put together abstractions that are useful in specific domains”. It’s very encouraging to hear that the approach is to wait and see how people use this feature before adding to it.Review on Github:Shared memory and atomics

Update: Two more features in ES8

Since this post was first published, one more feature has been finalized for ES8/ES2017, the lifting of template literal restrictions, which makes it much easier to embed alternative Domain Specific Languages as template literals.

We also had excluded one feature from our original list, support for trailing commas in parameter list calls. While this is not a major change in the language, it’s likely to save everyone working with JavaScript at least a few minutes per year, and hopefully discourage the practice of commas to start each line in a list of parameters or properties.

import, a dynamic import that was missing from the ES modules standard

Class and property decorators (already implemented in TypeScript)

Asynchronous iteration

Single Instruction Multiple Data (SIMD), which should speed up rendering and animation with things like WebGL, Canvas, etc.)

We’re excited to leverage the features in ES8, and look forward to the many more under consideration for this and future years. It’s refreshing to see the consistency and progress being made to keep improving JavaScript!

Update: Based on comments and feedback, it’s worth mentioning that yes, we know that the official names are ES2017 and ES2018. However, they are still called the 8th and 9th edition of ES internally. We think a better naming scheme would have been ES15, ES16, etc., but if everyone feels this strongly about the names, we’ll start calling them ES2017, etc. in future posts. Thanks again for the the feedback!

Thanks Axel Rauschmayer , I actually had that trailing commas in my original draft, but it seems like such a small addition (though it probably will save every JS engineer 10 minutes a year) that I left it out of the final version of the post.

Given the number of times in a day that I have to write or say ES*, I like the terser form of ES6, ES7, ES8, and the spec still calls them 6th edition, 7th edition, 8th edition, etc. In hindsight I wish they would have called ES6 ES15 and then there would be less confusion perhaps!

Aleksandr Strutynskyy

“Class and property decorators (already implemented in TypeScript)” seriously? why? for how long java guys with their awful classes will keep ruining javascript?

JavaScript has always had “Classes” (prototype-based inheritance), this is just syntactic sugar that was previously re-implemented thousands of different ways. These are not your Java OO classes, and it’s certainly not ruining JS as there’s nothing saying you must use them (even though they are just syntactic sugar on top of already existing language paradigms. Class is probably not even the right name for them, but there’s not a better name, so Class was chosen.

Also just because an idea exists in a language that you do not like (and that I’m not particularly fond of) doesn’t make it an idea that is universally bad.

Aleksandr Strutynskyy

I don’t think you understand the difference between prototype-base inheritance and classical inheritance, this is a basic JS interview question, quite sad. And classes are universally bad, google what Java creator would change in Java if he had to make it again, spoiler alert, he would get rid of classes. Then google on gorilla/banana problem with classes.

It doesn’t work like that. People being introduced to JavaScript will reproduce the patterns they see, especially if they are similar to their background experience (i.e. Java). From my experience as lead dev in a large TypeScript project, I realized that many developers tend to forget they are currently writing JS, and instead reproduce the old classical inheritance patterns over and over. They do not think about composition, or prototypal extension, or functions as first class objects. All the things that make JavaScript great are forgotten because of biased learning resources and opinionated frameworks. By criticizing ES6 classes and related features, we defend the original design of the language towards its detractors. This is a shared feeling in the JS community, see https://github.com/joshburgess/not-awesome-es6-classes/

The name Java comes from an early marketing alliance between Netscape and Sun and AOL.

To the bigger point, a language cannot really force people to learn things. That’s generally the role of frameworks, architecture patterns, documentation, and linting tools. This is where you and I can make a difference in what features are used. I was fairly opposed to ES6 Classes for over two years, but recently we spent a significant amount of time evaluating them for Dojo 2 and decided that we no longer consider them to be harmful when used the way they are intended.

Aleksandr Strutynskyy

Oh I’m sorry, you had to learn a different language and it turn out to be different than the one you used before?
Whats wrong with null|undefined, and whats so weird about loose typing in JS? And how any of that stops you from writing robust enterprise applications? JS is not perfect, has a ton of issues, but not the ones you mentioned.

Sylvain Pollet

> a language cannot really force people to learn things

I disagree. I learned a lot just by playing with Clojure, and I subscribed to a Scala training next month to improve my functional programming knowledge. I don’t plan to use these languages on professional projects, but I believe that learning different languages helps us to become better programmers. Many languages have been designed with a specific vision of software development. We should try to embrace this vision instead of distorting it to stay in our confort zone.

My point with “Java” in JavaScript is that the language has been disguised since its origins, trying to gain in attractiveness by deceiving people about its true nature and presupposed familiarity.

Nyancat

Yep, agree, null/undefined has ruined us. It would be a bit better if JS had a decent way of dealing with them. I don’t use them anymore, I use a simple implementation of Maybe monads and Eithers, as much as possible anyway.

Nyancat

Just to answer this question from my own personal experience, most bugs I create when working on my code are bugs that would have been caught by a robust type system. Trying to call a method on undefined, or accessing a prop on undefined, trying to compare a string to a number (whoops, I meant to get the length of the string!) or accessing a numbered index on something I expect to be an array, but comes through as a boolean for some reason. Being a JS dev almost my entire career has meant dealing with these kinds of issues has seemed normal to me, like it’s inevitable. But when I started trying to learn languages with robust typing, it changed everything for me. I used to think I never ran into “type” bugs, but now I see that almost all of them were exactly that. They don’t stop me, but they sure as hell slow me down in unexpected ways, all the time. In saying that, the caveat is, you can’t just get by with any old type system. Robust really must mean robust. If you can’t express anything in your type system, and have to rely on an escape hatch “any” type, then there’s no point in my mind.

after some years, I haven’t seen yet a practical use for null/undefined or generally null in programming languages. They are just the author of our nightmares, constant run-time errors.
I think the easiest way to be happy in JS is to accept the truth, there is no way to work in the basic category of sets, everything is lifted to the Nullable category with no practical syntax for working with it.

According to the JS specifications, the reason for the casting is historical, no logical. You cannot make assumptions of correctness, you have to verify the history.
JS is not a semantic language, the code is not intended to have any meaning, just to be run as it is.
Consider: null ? 1 : 0, 0 ? 1 : 0 and null == 0, that is an inconsistency but it has historical reasons to be like this.
As well undefined ? 1 : 0 is 0, why? no logical reason, how can you determine undefined is falsy? it is undefined, therefore the result should be undefined as well or rise an exception, since it is not computable.

a = null, a == undefined = true ? Why? a is a defined variable that has no value. Again, historical reasons. Come on, you fight a lost battle. null is recognized as a flaw of languages, his creator accepts it. So?

Nicolaie Constantinescu

undefined has a role in the compilation phase and that is kind of logic for the engine to link an identifier to a wildcard until the its value is assigned. And yes, used in ternary like that it is rather awkward to be evaluated to a falsy value…

Ícaro Motta

> I haven’t seen yet a practical use for null/undefined or generally null in programming languages. They are just the author of our nightmares…

It’s a common fallacy to make an argument based on the absence of evidence, rather than the existence of evidence. Perhaps you should look into Clojure, where nil-punning is even promoted. In Clojure land, you’re making hasty conclusions.

> everything is lifted to the Nullable category with no practical syntax for working with it.

Agree with you, language support is essential, but it’s not the “syntax” that matters. I think the word “syntax” is incorrectly used in this context.

Ícaro Motta

> most bugs I create when working on my code are bugs that would have been caught by a robust type system.

I have a very different personal experience. First of all we’d have to agree on what a bug is exactly. I think you’re focusing only on certain classes of bugs. Anyways, most, if not all codebases I ever worked on had “bugs” caused by numerous flaws not linked to types, e.g. poor understanding of the domain, lack of code reviews, flaky test suites or no tests at all, inconsistent performance, race conditions, browser inconsistencies leading to terrible user experiences, etc. Lots of different classes of bugs cannot be detected by any “robust type system”, so we should be careful not to put too many expectations on it, whatever robust means here.

> If you can’t express anything in your type system, and have to rely on an escape hatch “any” type, then there’s no point in my mind.

It’s true indeed. I’ve seen a lot of that in codebases using Flow and TypeScript…

Nyancat

Indeed, you make a good point. Most bugs that occur after delivery – or when passed from the dev to go through the QA/Testing pipeline – from what I see are often not strictly type-related bugs. I was mainly talking about my experience during the development process. Like, as I’m hacking away, and I’m trying to get a new function I just wrote to work, and after hours it turns out I was trying to call a method on a string when it was supposed to be a number, or other such cases. Sorry for the confusion!

Ícaro Motta

I understand your example and also feel that pain ;) There’s no definitive answer on how to improve this. Along with better validations from compilers and more robust type systems as you said, I believe practices like REPL Driven Development, TDD, and/or pair programming can help us during the development process.

Nyancat

Very true about TDD, that is a big boost to ensuring accuracy – combined with robust types, linting and type checking tools in our editors, and (for those who work well this way) pair programming all go towards improving the accuracy and quality of our code. It’s a hard habit to get into for all of these, but well worth it.

On the topic of Pair programming, as useful as it is for most people, I dont think its possible for everyone. I think the majority of people can, but there are oddballs like me whose way of thinking makes it way too confusing for others to pair with. Every time I join a new client on-site, there’s normally at least one other dev there who believes whole heartedly that pairing is for everyone, and always convinces me to give it another try, and they always end up frustrated with me being so awful to pair with that they give up within a few hours :P but unless one has a chaotic mind like mine, pairing should be a key part of any developers toolkit.

Ícaro Motta

Really good point about Pair Programming. A process should not be enforced, and I see Pair Programming as a process with many variations.

Nyancat

Almost forgot to ask you about REPL driven development, would you mind sharing any articles that you could recommend on the subject? I looked at a few google results but they weren’t much more enlightening than a definition of the acronym. Do you have any resources that get into how its used, and what the benefits are?

Somebody just read a wikipedia article about fallacies. Right?
Read my sentence again. It asserts I haven’t seen, who? I, did I see any single practical use? No. Therefore the whole sentence is true, it is not a logical trap. The extra content you implied is not my responsibility.
Nil is not null in Clojure. As well Nothing in Haskell is not. None of them will generate a NullPointerException in the screen of the user.
I understand your feelings, when the lack of arguments happens, it is easy to start to talk about fallacies and avoid the main topic.
It is indeed syntax. There is no way to generate a valid program that can compile and I can consider conformable to work with. If you like verbose syntax, do not tell me this is a fallacy.

The any “type” was definitely needed in the earlier days of TS, but is not needed much today after the additions to TS in 2.0 through 2.2, with a few exceptions (e.g. variadic kinds are not yet supported), and when adding types for an existing JS codebase where it’s not easy to express the intended type. That said, it’s a fallback/crutch that people rely on more than they should need to with TS unfortunately, though we’re pretty strict about this with Dojo 2.

In contrast, Flow basically makes everything any unless you tell it to be more strict, which is one of their primary selling points, which I don’t particularly like.

Aleksandr Strutynskyy

so you didn’t learn == vs === ? you do == in an interview and it will major red flag. that’s like lesson 1 for newbies, along with falsy/truthy types, what exactly confused you about undefined being falsy? again it boils down to LEARNING THE LANGUAGE.

Aleksandr Strutynskyy

here is the thing, type correction doesn’t mean program correctness. types are majorly overrated. what you need to do is unit tests.

Nyancat

I don’t disagree. Unit tests and types are both very useful parts of the correctness toolbox. I was primarily talking about the time I spend debugging a functions internals trying to find out why it’s failing a test, only to discover it’s a type mismatch. I get a lot of those, and moving to type safety helped me so much in that regard :)

Aleksandr Strutynskyy

well i don’t know what to say, never ever have those… i kinda find it weird, maybe it is related to your experience with other languages.

Nyancat

Possibly! I actually found it a sneaky kind of issue, and didn’t realise how many of them I was seeing until I discovered type safe languages, and it slowly dawned on me what things were issues of type mismatch, and it turned out to be happening to me on a daily basis. Things like passing the wrong key which would yield the wrong value (and often the wrong type), passing the wrong object to something that is expecting to call a method but the wrong object doesnt have that method, accidentally passing a string to a number boundary predicate (ha that one made me feel really stupid), it happens to me constantly when writing dynamic languages like JS. Maybe it’s just my brain thats broken ;) wouldn’t be too surprised if that was the cause!

Nyancat

Yeah, you make a good point about TS’ early days. I do like TS, but I remember day 1 of trying to write my first serious little app in TS and running into a missing feature of the type system that required either the greatest hack ever, or using any. And it hurt :( so I hold a bit of bitterness from that hehe.

Types in TypeScript are basically a terse way of writing unit tests for all types, they just get evaluated at transpile time, before tests are written. Especially since these type definitions are erased during transpilation.

The thing that is deceptive about JS being a dynamically typed language is we end up building a lot of type checking into our codebase. This becomes increasingly important when we work with codebases that are large and shared across teams.

In my opinion, the real benefit though of TypeScript isn’t actually types, but what having a type system makes possible, which is interfaces. Having the ability to succinctly say that an object has these methods and properties, some of which are optional and some of which are required, and being able to do that in a manner that follows both JS’ prototype-based inheritance, as well as importing and exporting interface definitions with ES modules, is really useful.

See my other reply, this is where interfaces are really useful, even more so than types (though interfaces need a type system to be meaningful or possible to express).

Nyancat

Yep, this is definitely a great feature, and one of the things I needed in my day to day work! Great explanation!

Ícaro Motta

> Somebody just read a wikipedia article about fallacies. Right?

It looks like you had to do some research on fallacies, right? Btw, I love Wikipedia ;)

> I haven’t seen yet a practical use for null/undefined or generally null in programming languages

Please, be mindful of generalizations. In Clojure, your assumption is incorrect. Also, try to be more specific in order to make discussions easier, e.g. “generally null in programming languages” is too open-ended.

> Nil is not null in Clojure. As well Nothing in Haskell is not. None of them will generate a NullPointerException in the screen of the user.

Again, asserting incorrect things. Clojure will scream null pointer exceptions all over to users if you make certain mistakes. I have no idea how you could possibly affirm that.

> It is indeed syntax. There is no way to generate a valid program that can compile and I can consider conformable to work with. If you like verbose syntax, do not tell me this is a fallacy.

Hey man, you sound really confusing and vague here too. What do you mean by “valid program”? What is a “conformable to work with” compiled program? What do you really mean by “verbose syntax”? What in the world a fallacy has anything to do with syntax?

But hey, you’re right, let’s get back to the main topic. We’re digressing now.

Let’s keep this about JS. Forget the fallacy stuff. There is no fallacies here. Keep in mind the “I haven’t seen”, it refers to my personal experience. Yours or absolute values don’t have impact on it.
Nil in Clojure, as far as I know, is a wildcard, it is an empty list, an empty string,… (I could be wrong, I don’t really care about Clojure)
null in JS, as far as it is, it is not a string, not an array, not a NaN, not a number. The typeof says it is an object, but it is not (bug that became a feature, historical reason).
You are the confused one, a valid program is understood as a program that can be compiled, for example: “({a:1}) + ({b:2})”, meanwhile “foo?.add(1)” is not syntactically correct, and it is not a valid program in JS.
verbose syntax means a verbose syntax, what don’t you understand about it?

oh no, you are quite wrong :) , indeed I know those. Those are just operators. The logic of those operators is different to the one of the if and ?:, check the specs of the language. false == undefined = false, false === undefined = false, undefined ? 1 : 0 = 0, false ? 1 : 0 = 0, in the if evaluation, undefined can be abstracted as false, while in == (the abstract equality) is not. The language is inconsistent with itself.
Come on, do not waste your time :) JS is required, however it is not good, Google made Dart and angular, Facebook has JSX, Microsoft typescript and JScript, there is elm, purescript, coffescript, and several more. There is a vastly ocean of people who recognize JS as a bad language and they made their languages to avoid it, and several of them are quite popular.
Regardless of what you can think, WebAssembly is coming to remove that requirement :)

There is no such thing as ES7, ES8, ES9, etc. The official naming scheme (that’s been in place for 2 years now) is ES2016, ES2017, ES2018, etc. Sure it’s 3 characters shorter but I don’t think that justifies the extra confusion naming things differently than the TC39 committee. Great review otherwise, thanks for putting it up!

kiwi

I don’t get you. If you are so angry about JS why do you use it? JavaScript has it’s own good points and bad points but it seems now that with all these changes people at ECMA want to make it a totally new language. I really like the announces of the new ES8 features but what has been done with ES6 was something that in my opinion wasn’t necessary.

As noted, I’m a bit stubborn with the new naming convention. It’s especially interesting right now, if you search Google for ES2017 spec, you are taken to https://tc39.github.io/ecma262/ which is titled the ES2018 Language specification, which says “This Ecma Standard defines the ECMAScript 2018 Language. It is the eighth edition of the ECMAScript Language Specification.” which is obviously wrong as the 8th edition should match up with the 2017 version of the spec, so I’m not sure what’s going on with that at the moment.

It reminds me of Java 2 vs. 1.2, which still lives on in the Java 8 vs 1.8 naming convention of marketing vs. internal usage. Mostly though I just prefer brevity for spec names, and don’t really want to use the full name of ECMAScript 2017, but I guess I’ll conform going forward. I still argue they should have just called them ES15, ES16, ES17 and merged the version number with the year if that’s what was wanted, as it’s not like they haven’t skipped a version number previously (e.g. ES4).

Personally I would have preferred if the names would have remained ES6, ES7, etc. ES15, ES16, etc as you say would also have been better I agree! But I think it’s more important that everybody uses the same names/terms to reduce community confusion and increase searchability. Even if the names kinda suck 😸

I guess you know the answer, it has a monopoly in the web front-end development. That is why I am interested.
I understand why it is a quite bad language, they have to provide backward compatibility, so every mistake in the language stays forever because JS doesn’t have versions, just the eczemascript has. Wouldn’t it be great to have a “use JS8” at the beginning of the file? and get rid of all the “bad parts”?

We actually had that back in the early days, e.g. JavaScript 1.0, 1.1, 1.2, etc., but this worked about as well as user agent strings unfortunately thanks to browser implementation behavior back then.

Aleksandr Strutynskyy

feels like talking to a wall, everything bounce back… i keep sayin this is lesson 1 in JS, undefined in JS is falsy, don’t use ==, use ===, and everything works fine, whats up with that bashing around? and btw JSX is html to JS, not a language. You just don’t understand the language, thats ok, get a couple of Crockford books, learn to code JS without using classes and “new” keyword, it will start making sense.

JSX is an independent language, it is not a subset of JS, it is not even related to html, it is xml, there for the X. html is not a subset of xml. xhtml is. Anyway, FB has flow :) and they compile their JS to ocaml, do not use FB as an example of how great JS is.

I told you, I know both == ===, actually they have names.
Why are you telling me to ignore the abstract equality? It is in the language for a reason, it is there! so the people will use it, and it is not considered a bug, lesson 1: learn to use both equalities and not ignore the abstract. And we will judge JS complete.
Cockford talks about the good parts :D so? do you get it? do you? there is a lot of bad parts. Indeed, there is a lot of bad parts.
There is a big effort to get rid of JS , several approaches. WA will free the browsers soon ;)

We probably started in 2013 to talk about the risks of defining and finalizing a module format without finalizing the spec for how modules are loaded, given our experience in working with AMD. And yes, it’s a real problem because when the implementation of module loading is not consistent, it leads to significant problems that are difficult to track down.

dino

SIMD and Observable won’t be in es2018 if ever:

– there’re doubts Observable should be a ES standard.
– Vendors have lost interest in SIMD. They will revisit again after wasm get shipped.

We’ve been pushing to try to get Observables standardized and may try to help with that as the original champion of it has not had time to push things forward. There is also some resistance because of the competing (and frankly far more complex) WHATWG Streams spec, which is available in Chrome Canary.

Also this list is now a few months old, and these changes change pretty quickly and abruptly at times! Thanks for the feedback.