It has been 9 years since JavaScript ES6 was introduced.
In ES6 release we've got important features as: lexical scoping ie. let
and const
, classes, arrow functions, template literals, destructuring, maps, sets and default parameters.
I clearly rembember how this release changed writing of JavaScript.
But what about subsequent releases? What have we got since then?
2016 ES7 has brought:
- Exponentiation operator
const square = 4**4
-
Array.prototype.includes()
[1,2,3].includes(3) // true
2017 ES8 has brought:
-
async
await
support -
Object.entries
Object.entries({ a: 1, b: 2 }) // [['a', 1], ['b', 2]]
-
Object.values
Object.values({ a: 1, b: 'hello' }) // [1, 'hello']
Object.getOwnPropertyDescriptors
- String padding functions:
padStart
,padEnd
2018 ES9 has brought:
2019 ES10 has brought:
-
Array.prototype.flat()
[1,2,[3,4]].flat() // [1,2,3,4]
-
Array.prototype.flatMap()
[1,2].flatMap((x) => [x,x*2]) // [1,2,2,4]
-
Object.fromEntries()
Object.fromEntries([['a', 1], ['b', 2]]) // {a:1,b:2}
- String.prototype new functions
trimStart()
trimEnd()
trimLeft()
trimRight()
2020 ES11 has brought:
- BigInt support๐โ
-
Promise.allSettled()
๐4 - Nullish coalescing operator
??
- Optional chaining
?.
- globalThis๐โ
-
export * as ns from 'module'
syntax for modules -
import.meta
๐โ
2021 ES12 has brought:
-
String.prototype.replaceAll()
'aaabbb'.replaceAll('a','c') // cccbbb
-
Promise.any()
๐5 - Logical assignment operators
??=
,&&=
,||=
-
WeakRef
referencing object but allowing it to be garbage collected -
_
separator allowed in number literals1_000_000 // 1000000
2022 ES13 has brought:
- top-level
await
- public, private, static class fields, static initialization blocks๐6
-
#x in obj
syntax, to test for presence of private fields on objects -
\d
new RegExp flag๐โ -
TypedArray
๐โ -
cause
property onError
objects useful when re-throwing error to access original error.๐โ -
at()
for Strings, Arrays and TypedArrays-
'abcd'.at(-1) // d
,'abcd'.at(2) // c
-
-
Object.hasOwn()
๐โ a betterObject.prototype.hasOwnProperty()
2023 ES14 has brought:
- New methods on
Array.prototype
-
toSorted()
returns new copy of sorted array -
toReversed()
returns new copy of reversed array -
with()
๐โ findLast()
findLastIndex()
toSpliced()
-
-
#!
shebang support
2024 ES15 has brought:
-
\v
new RegExp flag๐โ -
Promise.withResolvers()
convinient promise construction๐โ -
Object.groupBy
,Map.groupBy
now easier to group items based on property/value๐โ -
Atomics.waitAsync()
useful when working with shared memory buffers๐โ -
String.prototype.isWellFormed()
andString.prototype.toWellFormed()
checks for well-formed Unicode
What is your favourite feature from above list?
If you enjoyed this article you can join my newsletter to get dose of weekly craftsmanship.
Get dose of Craftsmanship here
References
๐1 Async iterator support (source)
const asyncIterator = (async function* () {
yield 1;
yield 2;
yield 3;
})();
(async () => {
for await (const value of asyncIterator) {
console.log(value);
}
})();
// Logs: 1, 2, 3
๐2 Async generator support (source)
async function* createAsyncGenerator() {
yield await Promise.resolve(1);
yield await Promise.resolve(2);
yield await Promise.resolve(3);
}
const asyncGen = createAsyncGenerator();
asyncGen.next().then((res) => console.log(res.value)); // 1
asyncGen.next().then((res) => console.log(res.value)); // 2
asyncGen.next().then((res) => console.log(res.value)); // 3
๐3 Promise finally()
(source)
Schedules a function to be called when the promise is settled (either fulfilled or rejected).
fetch('https://api.example.com/json-data')
.then(response => response.json())
.then(json => console.log(json))
.catch(error => console.log(error))
.finally(() => console.log('finally() called!'));
๐4 Promise.allSettled()
(source)
This returned promise fulfills when all of the input's promises settle (including when an empty iterable is passed), with an array of objects that describe the outcome of each promise.
const promise1 = Promise.resolve(3);
const promise2 = new Promise((resolve, reject) =>
setTimeout(reject, 100, 'foo'),
);
const promises = [promise1, promise2];
Promise.allSettled(promises).then((results) =>
results.forEach((result) => console.log(result.status)),
);
// Expected output:
// "fulfilled"
// "rejected"
๐5 Promise.any()
(source)
const promise1 = Promise.reject(0);
const promise2 = new Promise((resolve) => setTimeout(resolve, 100, 'quick'));
const promise3 = new Promise((resolve) => setTimeout(resolve, 500, 'slow'));
const promises = [promise1, promise2, promise3];
Promise.any(promises).then((value) => console.log(value));
// Expected output: "quick"
๐6 public, private, static class fields, static initialization blocks
class ExampleClass {
instanceField;
instanceFieldWithInitializer = "instance field";
static staticField;
static staticFieldWithInitializer = "static field";
#privateField;
#privateFieldWithInitializer = 42;
static {
this.staticField = 'Static initialization block'
// Why? We can use here try...catch block.
// More than one of these blocks can be declared.
}
publicMethod() {}
static staticMethod() {}
#privateMethod() {}
static #staticPrivateMethod() {} // ExampleClass.#staticPrivateMethod()
// allowed to be called only within class
}
// The name of a static property (field or method) cannot be prototype.
// The name of a class field (static or instance) cannot be constructor.
Top comments (0)