This article was originally posted on my blog. Head over to inspiredwebdev.com for more articles and tutorials. Check out my JavaScript course on Educative to learn everything from ES6 to ES2020.
Every year since 2015, JavaScript
has been receiving constant yearly updates to its specification with new interesting features added.
Despite the release of ES2021 still being far in the future, we can already have a look at what's to come since many features already reached stage 4 and will be included in the specification.
For those of you who don't know, there are 4 stages in the proposal process, with the 4th one being the last one which marks the proposal as finished.
As a developer, it's important to stay updated with the new specs of a language and if you feel like you've been left behind by the many updates that JavaScript
received in the past years, I can recommend you my book that covers everything from the basics of the language all the way to the latest ES2020 specs, including a little intro to TypeScript
. You can read it for free on Github where you will also find links where to buy the ebook or you can check out my course on Educative
Now, let's get started with the first of the new ES2021 features:
String.prototype.replaceAll
String.replace
is a useful method that allows us to replace a pattern in a string with something else. The problem is that if we want to use a string
as a pattern and not a RegEx, only the first occurrence will get replaced.
const str = 'I like my dog, my dog loves me';
const newStr = str.replace('dog', 'cat');
newStr;
// "I like my cat, my dog loves me"
As the name implies, String.replaceAll
will do exactly what we need in this scenario, replace all the matching pattern, allowing us to easily replace all mentions of a substring, without the use of RegEx:
const str = 'I like my dog, my dog loves me';
const newStr = str.replaceAll('dog', 'cat');
newStr;
// "I like my cat, my cat loves me"
Promise.any
During the past years we've seen new methods such as Promise.all
and Promise.race
with ES6, Promise.allSettled
last year with ES2020 and ES2021 will introduce a new one: Promise.any
.
I bet you can already tell what it does from the name of the method.
Promise.any
shorts-circuits once a given promise is fulfilled but will continue until all promises are rejected.
Don't get confused with Promise.race
because with race
, the promise short-circuits once one of the given promises resolves or rejects.
They have similar behavior for what concerns fulfillment but very different for rejection.
If all the promises inside of Promise.any
fails, it will throw an AggregateError
(a subclass of Error
) containing the rejection reasons of all the promises.
We can use it like this:
// example taken from: https://github.com/tc39/proposal-promise-any
Promise.any(promises).then(
(first) => {
// Any of the promises was fulfilled.
},
(error) => {
// All of the promises were rejected.
}
);
Logical Operators and Assignment Expressions
With ES2021 we will be able to combine Logical Operators (&&
, ||
and ??
) with Assignment Expression (=
) similarly to how it's already possible to do in Ruby.
If you skipped on ES2020 you may not be aware of ??
which is the nullish coalescing operator. Let's look at an example:
const a = null ?? 'test';
// 'test'
const b = 0 ?? 'test';
// 0
The nullish coalescing operator returns the right hand-side when the left-hand-side is null
or undefined
, otherwise it returns the left hand-side. In the first example the left-hand-side was null
thus it returned the right-hand-side while on the second example it returned the left-hand-side because it was neither null
nor undefined
.
Moving back to ES2021 stuff, in JavaScript
we already have many assignment opeartors like the following basic example:
let a = 0;
a +=2;
// 2
But with this new proposal we will be able to do the following:
a ||= b;
// equivalent to a = a || b
c &&= d;
// equivalent to c = c && d
e ??= f;
// equivalent to e = e ?? f
Let's go over each one by one:
-
a ||= b
will returna
ifa
is a truthy value, orb
ifa
is falsy -
c &&= d
will returnd
if bothc
andd
are truthy, orc
otherwise -
e ??= f
will returnf
ife
isnull
orundefined
otherwise it will returne
Numeric Separators
The introduction of Numeric Separators will make it easier to read numeric values by using the _
(underscore) character to provide a separation between groups of digits.
Let's look at more examples:
x = 100_000;
// 100 thousand
dollar = 55_90;
// 55 dollar 90 cents
fraction = 0.000_1;
// 1 thousandth
WeakRefs
From MDN: A weak reference to an object is a reference that does not prevent the object from being reclaimed by the garbage collector.
With this new proposal for ES2021, we will be able to create weak references to objects with the WeakRef
class. Please follow the link below to read a more in-depth explanation.
Intl.ListFormat
The Intl.ListFormat
object is a constructor for objects that enable language-sensitive list formatting.
Looking at an example is easier than explaining it:
const list = ['Apple', 'Orange', 'Banana'];
new Intl.ListFormat('en-GB', { style: 'long', type: 'conjunction' }).format(list);
// Apple, Orange and Banana
new Intl.ListFormat('en-GB', { style: 'short', type: 'disjunction' }).format(list);
// Apple, Orange or Banana
You are not limited to English, let's try with a few different languages:
const list = ['Apple', 'Orange', 'Banana'];
// Italian
console.log(new Intl.ListFormat('it', { style: 'long', type: 'conjunction' }).format(list));
// Apple, Orange e Banana
// Spanish
console.log(new Intl.ListFormat('es', { style: 'long', type: 'conjunction' }).format(list));
// Apple, Orange y Banana
// German
console.log(new Intl.ListFormat('de', { style: 'long', type: 'conjunction' }).format(list));
// Apple, Orange und Banana
Pretty neat uh? For a more detailed look at this specification check out the link below.
dateStyle and timeStyle options for Intl.DateTimeFormat
We can use dateStyle
and timeStyle
to request a locale-specific date and time of a given length.
// short
new Intl.DateTimeFormat("en" , {
timeStyle: "short"
}).format(Date.now())
// "2:45 PM"
// medium
new Intl.DateTimeFormat("en" , {
timeStyle: "medium"
}).format(Date.now())
// "2:45:53 PM"
// long
new Intl.DateTimeFormat("en" , {
timeStyle: "long"
}).format(Date.now())
// "2:46:05 PM GMT+7"
Now let's try with dateStyle
:
// short
new Intl.DateTimeFormat("en" , {
dateStyle: "short"
}).format(Date.now())
// "7/25/20"
// medium
new Intl.DateTimeFormat("en" , {
dateStyle: "medium"
}).format(Date.now())
// "Jul 25, 2020"
// long
new Intl.DateTimeFormat("en" , {
dateStyle: "long"
}).format(Date.now())
// "July 25, 2020"
You can pass whatever locale you want and you can also pass both dateStyle
and timeStyle
options at the same time, choosing between the three options of 'short', 'medium', and 'long' that best suit your needs.
What's the feature you are most excited to try? Leave a comment down below, for me, it's probably the combination of Logical Operators and Assignment Expressions, I love my syntax to be short and clean.
If you want to learn everything about JavaScript from ES6 all the way to ES2020, please check out my book available to read for free on Github. A course is also on Educative
Top comments (10)
This one is a really illustrative post, thanks for sharing!
What is the O notation of replaceAll? Is it still O(n)?
Regarding:
e ?? =f will return e if it's null or undefined otherwise it will return f
I think you mean:
e ??= f will return e if it's not null or undefined otherwise it will return f
Yes, you are right, my bad. Thanks
Great if you could edit it to correct it :)
Yep, i did it
Regression error:
e ?? =f will return f if it's null or undefined otherwise it will return e
(notice the incorrect "??=" sign, and that "it's" should not refer back to f)
Should be:
e ??= f will return f if e is null or undefined otherwise it will return e
Whoops, you are right, i rush to fix and made another mistake ahha thanks
Very useful, can not wait to use ES2021.
Another very useful one, optional chaining.
a = b?.c
// equivalent to a = b && b.c