If you’re a JavaScript developer, then you’ve probably heard of ECMAScript before – it’s the specification that prescribes how JavaScript (and other implementations, like TypeScript) must behave. It has a set of specifications that it must meet to be a valid ECMAScript implementation.
Due to the rising popularity of front-end JavaScript frameworks, NodeJS and TypeScript, the specification added a lot of syntactic features in 2015. Since then, we’ve seen an update every year that adds at least a few features to the specification. In this post, we’ll look at some of the features in the latest spec, ECMAScript 2017, and look at some of the proposals for the future.
async / await
One of the biggest updates in this spec was asynchronous functions. It introduces the async and awaits keywords, which should be used to prefix function declarations and function calls, respectively. It’s an upgrade to Promise – when you prefix a function declaration with async, you’re just saying that your function will return a Promise.
Similarly, when you use await, you’re postponing the execution of whatever comes next until your awaited function resolves. Because of that, you can use async functions in the same way as you’re using promises now, and you can await promises just like you can async functions. The only limit here is that you can only use the await inside async functions.
String padding
String padding was also added in this patch. Not sure if the left-pad apocalypse had anything to do with it. String padding is pretty simple – it’s used for string formatting, so you can ensure the string has a specific length.
You can even pad it with a string.
Trailing commas in functions
Another neat syntax update is allowing the use of a trailing comma in functions. This allows you to add that final comma to functions, just like you can to arrays and objects.
Before, calling this would throw a SyntaxError:
This is great if you have functions with a variable amount of arguments, like in the example above, and want to follow the comma-dangle rule of ESLint – which is great when adding arguments and reduces merge conflicts.
Objects
In addition to Object.keys, we now also have Object.values and Object.entries. Both of these functions are another step into a more functional JavaScript, as they return arrays through which you can then map/reduce/filter.
Object.values is the opposite to Object.keys, as it returns the values of an object.
Object.entries is a combination of both – it returns an array of key-value arrays.
Object.getOwnPropertyDescriptor was also added, which returns an object’s properties with their descriptors. An object’s properties are properties that were defined for that object only and are not inherited. It’s not very useful for everyday development so that I won’t go into the details, but you can read more about it here if you’re interested.
Shared memory and atomics
Just like web workers solved the issue of parallelism in Javascript, which is a single-thread environment, shared memory solved the communication between your main thread and your background workers. Yes, you have the postMessage method, but it’s got a lot of limitations as to what you can pass to it.
SharedArrayBuffer allows you to create a chunk of memory that can be shared between multiple threads. You can create a memory buffer, pass it to your background worker using postMessage and that’s it. Any changes you make to that array will be reflected to your background worker.
Here’s a simple demonstration:
Then you receive the data in your web worker.
This has one downside though; you can’t tell when a change has been made to the shared memory, apart from checking it in an interval. What if you want to check if a flag has been set, but don’t want to start up an interval? You could use a while loop, checking the value in each iteration, but this doesn’t work as you would expect. Due to compiler optimizations, your loop won’t see the change made and continue looping. Thanks to Atomics, you can solve this by using special methods for storing and reading data to your shared memory.
There are a few more methods in the Atomics namespace that I won’t talk about here, but you can read this blog post, which covers shared memory and atomics.
ESNext
The language is evolving faster than ever before. There are a ton of new proposals. Here are a few that I’m looking forward to:
Pipeline operator
The pipeline operator proposes a new operator, |>, inspired by pipes from many other functional programming languages, as well as UNIX’s Bash. Like many features in ECMAScript, it’s another syntactict sugar. This time, it’s for functions that only accept one argument. It’s similar to method chaining, but easier, since it can be used with any function, and not object prototypes only.
It solves the readability of nested function calls, and even allows use of decorators.
Let’s say you have the following functions:
Right now, if you wanted to chain them together, you’d have to write this unreadable line of code. It’s not very readable, as you have to start reading from the inner-most bracket out.
With the pipeline operator, the flow is much clearer, as you can simply follow the code and understand what’s going on.
You can read much more about it on its proposal repository.
Array flattening
A proposal to introduce Array.flatten and Array.flatMap methods was added recently. This would add methods that flatten arrays, which I have to do a lot of the time.
Say you have an array of depth n that you want to flatten completely. Instead of calling [].concat.apply([], array) n times, you could simply call array.flatten(n).
Array.flatMap is similar, except that it first maps array elements and then flattens them to the depth of 1. It’s the same as calling array.map(func).flatten(1).
You can read more on this here.
Promise.try
Ever wanted to start a promise chain without a promise? Or do you hate it when you have to handle both synchronous and asynchronous errors in your code? With Promise.try you can solve both of those problems. All of your synchronous errors (throws) will be handled like it would be in a promise, so you get your error in your catch callback, and on top of that, you can start a promise chain with an actual promise.
Read the proposal here.
That’s about it. I highly recommend trying these out to get a better understanding. They will improve your code readability (if used correctly) and your quality of life when programming.