13 JavaScript features from ES7–10 you might not know about


The JavaScript development community has become quite comfortable with the new language constructs introduced with ECMAScript 2015 (aka ES6). Classes, arrow syntax, template strings, let & const, map, modules and plenty more have become commonplace and browser support is very good, apart from IE11. But work on ECMAScript didn’t stop there. Here are some highlights from ES7, 8, 9 and 10, which you might not be as aware of.

ECMAScript 2016 (ES7)


So we can now say if(numbers.includes(2)) rather than if(numbers.indexOf(2) !== -1).

Exponentiation operator

We can now do base**exponent instead of Math.pow(base, exponent).

ECMAScript 2017 (ES8)


Yes, this one is a biggie and essentially brings the same functionality to JavaScript as was available in C#. Bear in mind that client-side JavaScript is inherently single-threaded (at the moment) so promises will still be executed one by one.


We’ve had Object.keys() for a while, to return an array of the Object’s property names. Object.values(foo) returns an array of the foo’s property values.


In a similar vein, Object.entries(foo) returns both the property keys and values, for example, [[“a”,1],[“b”,2],…]. This might make it easier to use the object in a loop or map.

String padding

We can now use padStart and padEnd to pad a string to a certain length. For example, ‘foo’.padEnd(6, ‘1234’) gives us ‘foo123’. If we replaced the 6 with a 9 we’d get ‘foo123412’.

Trailing commas

You can now have a trailing comma after the last parameter to your function. If that’s your thing.

ECMAScript 2018 (ES9)


You can now use named group captures by adding ?) to the front of a block in your regex. For example, if you ran the regex /(?\d{4})-(?\d{2})-(?\d{2})/u>) against the string ‘2019-01-02’ then the groups property of the result would give you access to year, month and day properties with those values.

You can also now use lookbehind assertions (?<= ... ) and (?<! ... ), which let you check that some string exists or does not exist (respectively) immediately before another.


The rest operator ... (3 dots) lets us extract all the properties of an object that are not already extracted. Let’s say we have a person object with properties firstName, lastName, dob, address, niNumber. We could say let { firstName, lastName, ...otherDetails } and the otherDetails property would be set to an object containing the other three properties.


Spread uses the same ... operator but uses it to take an object’s properties and create them as properties in a new object. Carrying on from the example above, we could say let personDetails = { ...otherDetails } and our personDetails object would be created with properties dob, address and niNumber.

Finally for promises

A finally() instance method is now available for promises, which will run as a callback after either resolve or reject has completed.

ECMAScript 2019 (ES10)


The flat() method creates a new array with any sub-arrays concatenated into it. For example, if we had an array of [1,2,3,[4,5],[6,7]] and we called .flat() on it we would get a new array of [1,2,3,4,5,6,7]. If we had an array of [1,2,3,[4,5,[6,7]]] and called .flat() on it we could get a new array of [1,2,3,4,5,[6,7]]. If we had called .flat().flat() then we’d have had the same result as the first example.


If we have an array of key-value pairs, we can call .fromEntries() on it and get an object where those pairs are now properties of our object.