JavaScript, ES6, ES7, ES10 where are we?

JavaScript, ES6, ES7, ES10 where are we?

Image for post

What is JavaScript? According to Wikipedia, it is a scripting language that conforms to the ECMAScript specification. ES6, ES7, etc? You probably have heard those names, you also have most likely been using ES6 for a while (with Babel in a lot of cases).

I?m sure most of you are using many different fancy ES6 features without asking yourself: Is this really ES6, is this still a feature unsupported by Browser? Between you and me, how much do you know about what Babel still transpiles in 2019 and how much it doesn?t? Have you refreshed your knowledge about what?s in ES? What?s been removed since the first proposal for ES6? What has been added since the initial ES7 proposal?

Because I believe everybody should be concerned about when we?re finally getting a replaceAll function in JS, let?s sit and have a bit of a retrospective on what is the current state of the ES-scene. What?s coming, what?s been fully integrated since the infancy of Babel and ES6? After reading this article, you will be an ES-10/10! (Sorry, that was the best one I had!).

A bit of history and science

Let?s travel back in time! If, like me, you have first heard of ES6 and Babel around 2014?2015, you most likely still assume things are more or less in the same place than they were. That?s fair enough, since thanks to Babel, we only have a little to care about what?s actually going on behind the scene. But as you probably imagine, those ?proposal stage? functionalities that Babel allowed us back then to use before they were available, didn?t stay ?proposal stage? features for 5 years.

And in order for me to stop air-quoting ?proposal stage? while writing this article (it?s very hard to do air-quote while typing), I think it would be useful to give you people a refresher of what the different stages for a JS feature to be incorporated are.

Image for post

Essentially, the features go through stages from 0 to 4, 0 being the earliest stage, and 4 being ?ready to release?.

Image for post

Stage 0 are pure ideas someone drops, it is groomed to a Stage 1 proposal, reviewed and discussed until it reaches Stage 3, to finally be prioritized into a Stage 4. Once a feature reaches Stage 4, it is implemented in the browsers and scheduled for release.

Get all the deets here: https://tc39.es/process-document/

ES6 and ES7 ? reminder

I?m not going to insult you, and write yet-another ES6 introduction?But actually, I?m going to do it. In a nutshell, ES6 (or ES2015) is the batch of features that passed Stage 4 as per the 2015 milestone. In other words, if you have a good understanding of ES6 and some knowledge of ES7, you have about 4 years to catch up on?No pressure.

Let?s take a look at what?s officially part of ES6. By the way, all those features are officially supported across browsers. In other words, you do not need Babel to use any of them (unless you support IE 11, which is missing a few).

In ES6 we have:

The ability to create and inherit classes.

class MyComponent extends React.Components {}

ES6 modules with import and export.

import * from ‘React’;export default MyComponent;

Generators

let fibonacci = { *[Symbol.iterator]() { let pre = 0, cur = 1 for (;;) { [ pre, cur ] = [ cur, pre + cur ] yield cur } }}

We also have: Templates, arrow functions, Promises, new numbers, Const/Let, typed array, array destructuring, Map/Set, Symbols. List of all features here: http://es6-features.org

Have you noticed? Decorators, Object destructuring (like React props: {?props}) and so on are not part of ES6!

About ES7 (ES2016) here?s what we have. It is quite a small update:

  • The exponentiation operator base ** exponent
  • Array includes array.includes(myItem) // true or false

Source: http://ecma-international.org/ecma-262/7.0/

As you?ve probably noticed, no, Async/Await is not a part of ES7, but ES8!

ES8, ES9, ES10

Everyone who has had a JavaScript-related interview in the past 2 years, has been asked at least 1671 times what ES6 is, and what feature it brings. But anyone noticed how JS obviously didn?t suddenly stop at ES6 nor ES7, yet, no one is asking you about it? Here?s your opportunity to make things right!

In ES8 (ES2017), here are the available features:

  • Object.entries / Object.values (Array?s values / key equivalence for objects)
  • String padding myString.padStart(2); // or padEnd
  • Trailing comma function test(a,b,c, ) // notice the comma after c
  • Atomics and shared memory: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Atomics

And of course, Async / Await functions:

async MyAjaxGetCall(url) { return ajax.get(url)}const response = await MyAjaxGetCall(“/getUsers”);console.log(response) // response is available without using promise.then

If you?ve followed the article, by now you should get it: With only little exceptions, those features being Stage 4, you are able to use them in browser without Babel (that said, ES8 being ES2017, it is still pretty recent and some implementations like Edge and Opera?s native engine are lagging behind a bit).

Image for post

Moving on to ES9. Just like ES8 and ES6, ES9 (or ES2018) is a pretty major update:

  • Lifting template literal restriction (https://tc39.es/proposal-template-literal-revision/). Now allow complicated syntax (ex: LaTex) to be used in templates
  • Asynchronous iterators: Makes it possible to use iterator for async operations like reading a HTTP stream (https://tc39.es/proposal-async-iteration/) as well as the introduction of for-wait-of
  • Promise.finally: https://github.com/tc39/proposal-promise-finally
  • Object destructuring. Yes! Finally here, you?ve been using it for years, well, it is a ES9 feature. Reminder for non-React developers: It allows you to: myNewObject = {a,b,c, ?object}
  • Also include unicode escape and improvements to Regexes (here, here and here).

Image for postMost browsers support those features already!

Finally, moving on to ES10 (Or ES2019)!

  • Array.flat: [[1,2],3]).flat() // [1,2,3]
  • Array.flatMap: equivalent of map().flat()
  • Object.fromEntries: reverse operation from Object.entries (see here)
  • String.trimStart() & String.trimEnd(): Remove extra spaces in a string
  • Optional Catch binding: remove the need to add a param to the catch (Now you can do } catch {instead of } catch(e) {
  • Function.toString has been revisited to have a consistent behaviour ???
  • Symbol Description
  • BigInt ? arbitrary large numbers (Thanks @redeyes2015 for correction)
  • Improvement on Unicode support for JSON.stringify()
  • Array.sort now retains order if keys are equal

const array = [ {key: 2, value: ‘d’}, {key: 1, value: ‘a’}, {key: 1, value: ‘b’}, {key: 1, value: ‘c’},];array.sort(…)/*[ {key: 1, value: ‘a’}, {key: 1, value: ‘b’}, {key: 1, value: ‘c’}, {key: 2, value: ‘d’},]*/

  • Make JavaScript a superset of JSON (see details here)

What about ES5?

If ES6 is ES2015, and ES7 is ES2016, can you guess what ES5?s year is?

?You lost! (Unless you actually know, but since I can?t actually hear you, I?m assuming that you lost). ES5 is ES2009!

It doesn?t stop here, before ES5, the last ES update was in 1999!

Image for post

As you can see, from 97 to 99, updates were pretty frequent, then ES5 was going to be the only update in 16 years!

Image for post

How do we explain that? Well, in my opinion, there are two factors to this. The first one is technical: JavaScript sucks. Honestly, it does. Back then, we had a few alternatives to JS: Java Applets, ActiveX, and even Flash.

Up until 2011-ish (when Chrome started being a bullet) not only those technologies were an order of magnitude faster than JS, but they also already had most of the features we are still struggling to get in JS nowadays. (Java has all the language features like class and decorators, support multi-threading, OpenGL, Sockets, etc?). When Chrome and Google entered the scene and announced in 2013 that Java was out (and then Flash followed), the crusade to make JS catch up with its competitors was on. Two years later, we had ES6 at our doors.

The second factor is economical: 2000 is the year of the Dot-com bubble burst. For the youngest of you, imagine what bitcoin has been a few years ago, Internet startups were the same in the late 90s. Startups were adding .com at the end of their names to get enormous venture investments (just like we have a pledge of mySuperStartup.ai nowadays) until the value suddenly dropped in the 20s. This is a very rudimentary explanation, and I invite you to take a look at the wikipedia article for a better one.

The point is that Internet stopped gaining the traction it needed in order to make JS and web-related technologies a focus. Later on, with the rise of Amazon, Facebook and Google, the web had a new reason to be, and a new reason to thrive. It made it logical that we pick JS back up! Google was made public in 2004, Chrome was released in 2008, and became the most popular browser in 2014: one year before ES6 arrived.

What?s Missing? (Rejected proposals)

Here?s a non-exhaustive list of proposals that never made it to Stage 4. You can read more here: https://github.com/tc39/proposals/blob/master/inactive-proposals.md

Object.observe

This one is probably the biggest rejection of all. It initially allowed JS to observe any values in the code :

var obj = { foo: 0, bar: 1};Object.observe(obj, function(changes) { console.log(changes);});obj.baz = 2;// [{name: ‘baz’, object: <obj>, type: ‘add’}]

This was a great feature, and obviously, you can do it from your code (or with a polyfill) but implementing it in the browser was the promise of a faster reactive code (ex: Angular uses a lot of observing). It was withdrawn because they couldn?t come to an implementation with constant performance. More details here.

Cancelable Promises

Self-explanatory, a feature, I?m sure, is not the only one missing. The idea is to allow developers to cancel the execution of any promise at any time.

The use cases vary, for example, to have client-side timeout on async operation, or for example, if you have a tab-driven navigation system, and the user clicks a tab before you had time to load the content of the current tab.

blcks

I?m only mentioning this one because I like the name, but also because it?s a nice feature comparable to Go Routines or C# Tasks.

const blck = await {| // This code is Async, but most importantly, executed in another thread|};

Others

A few other interesting proposals have been made, like callable constructors. Most of those are either withdrawn because the original author did so, or rejected because they conflict or overlap with existing/planned features.

What?s Next?

A few exciting things are in Stage 0?3 at the moment. I thought I would highlight a few:

Observables (Stage 0)

Observe has been rejected, but the battle doesn?t stop and Observable are a proposal aiming at improving the API in order to remove the performance bottleneck experienced with Observe().

Observable

The Observable constructor is the %Observable% intrinsic object and the initial value of the Observable property of the?

tc39.es

String.ReplaceAll (Stage 3)

Because seriously, what the he** 😀

tc39/proposal-string-replaceall

Champion: Mathias Bynens (Google, @mathiasbynens). This proposal is at stage 3 of the TC39 process. Currently there is?

github.com

Top Level Await (Stage 3)

Using Await requires you to be in an async function, meaning you can?t simply drop a script tag with an await in it, which doesn?t necessarily make sense and is a limitation to ES6 Modules working seamlessly in browsers. It also allows you to perform fetch and what not.

// You can do this in a .js file:fetch(…).then((res) => something = res);// But you can’t do this unless you have a Async keywordconst res = await fetch(…);

tc39/proposal-top-level-await

Champion: Myles Borins Status: Stage 3 Top-level await enables modules to act as big async functions: With top-level?

github.com

Optional Chaining

Also known as Elvis Operator (I?ll keep using that name and you can?t stop me!), allows you to easily explore objects with no error being thrown:

const test = myObject && myObject.a;// equivalent toconst test = myObject?.a;

It is called Elvis Operator because the original operator ?: looks like Elvis when seen sideways.

The proposal also mentions a Nullish coalescing operator which I hope we are also going to find a better name to:

let x = 0 || 1; // x is 1 because 0 is falsylet x = 0 ?? 1; // Since 0 is defined, x is 0

Conclusion and F.A.Q.

That was long! Pretty sure, you won?t remember it all, and frankly, I won?t either! Hopefully, this gave you a good overview of everything, and encouraged you to re-think the way you think about JavaScript! I?d like to start the FAQ with the most important question of all:

Do I still need Babel?

Very good question! Considering most common features of JS (ES6 to ES9) are fully implemented in the browser aside from IE11. You might think: ?Well, then it?s not good enough?. But the answer is not good enough, and because you make a choice, you should consider:

? IE11 is currently as I write this, 1.86% of the browser population. But not supporting IE11 doesn?t mean you lose 1.86% of your audience, as you should consider that people are capable of switching browser, and also that your target audience might actually use IE11 at a much lower % (ex: if you target younger people or tech enthusiasts).

? Is supporting IE11 giving you more revenues than the money you lose not supporting it? Developing for IE11 is more than just using Babel. You need to test every feature on that browser too, because even with Babel, some of them will break, and then find fixes for all those issues. The overhead cost might not be worth it.

Also, using native functions rather than Babel?s transpiled code can be up to 3x times faster as highlighted by this benchmark: https://www.inovex.de/blog/node-js-10/ . Babel also increases your bundle size, and finally, it will slow down your build time when you develop. Hence why you should reconsider using Babel in every project!

Babel slows down code vs. using native functions, increases bundle size and slows down build time. Do you really need it in every project?

Why is it adding new keywords like let instead of updating?

You might wonder why JS introduced let instead of improving the existing var keyword. The answer is simple: It is done to keep backward compatibility. You wouldn?t want to break the web, huh? (I mean? for real, this time!)

What about Typescript?

Typescript?s rule is to implement Stage 3 proposals.

Where can I find out more about it?

Github and the official website are here:

tc39/proposals

Tracking ECMAScript Proposals. Contribute to tc39/proposals development by creating an account on GitHub.

github.com

Specifying JavaScript.

This section features proposals that are in Stage 3 of our process, which means they are close to completion. How to?

tc39.es

16

No Responses

Write a response