![]() |
VOOZH | about |
For those who do not know, TC39 is the organization behind the standardization of the ECMAScript (JavaScript) specification. Ever since the major 2015 ES6 release, it has become the norm to release new features yearly.
π New Es2021 FeaturesFor a feature to be added to a yearly release, it has to go through four proposal stages, with the final stage being approval. Letβs take a look at the five feature proposals that are currently in the final stage, with an anticipated release date for mid-2021.
The Replay is a weekly newsletter for dev and engineering leaders.
Delivered once a week, it's your curated guide to the most important conversations around frontend dev, emerging AI tools, and the state of modern software.
The new logical assignment operators &&=, ||=, and ??= are quite similar to the existing logical operators and are quite useful for assigning default values to variables.
||=)x ||= y
The logical OR assignment operator is a short-circuit operation just like the logical OR operator (||). The expression above is identical to x || (x = y), which means that y will only be assigned to x if x is falsy. Otherwise, x retains its original value.
Example:
const giveKey = () => {
//perform randon computations
return "somekey";
}
let userDetails = {name:"chika", age:5, room:10, key:""}
userDetails.key ||= giveKey()
console.log(userDetails.key)
//output : somekey
console.log(userDetails.key) returns "somekey" because the original key value was an empty string, which is a falsy value.
&&=)x &&= y
The logical AND assignment operator is the opposite of the logical OR assignment operator. In this case, y is only assigned to x, if and only if x is a truthy value. Otherwise, it retains its original value.
Example:
const deleteKey = () => {
//perform randon computations
return " ";
}
let userDetails = {name:"chika", age:5, room:10, key:"990000"}
userDetails.key &&= deleteKey()
console.log(userDetails.key)
//output : ""
userDetails.key &&= deleteKey() returns an empty string from the deleteKey function because the previous value of userDetails was a number, which is a truthy value.
??=)x ??= y
The logical nullish operator only assigns y to x if x is nullish (i.e., either null or undefined).
Example:
const getKey = () => {
//perform randon computations
return "somekey";
}
let userDetails = {name:"chika", age:5, room:10,}
userDetails.key ??= getKey()
console.log(userDetails.key)
//output : "somekey"
Here the output is "somekey" because userDetails.key does not exist in the response object (i.e., it is undefined).
String.replaceAllconst newString = oldString.replaceAll(pattern, replacement);
The replaceAll method returns a new string in which all occurrences of a pattern are replaced by a replacement passed to it. The pattern parameter can either be a string or a regex pattern, and the replacement can either be a string or a function that creates a new string to replace the pattern.
The replaceAll method is a sequel to the String.replace method, which only replaces the first occurrence of the pattern with replacement.
Example:
const str = "Linda is a self-taught developer.Linda will rule the world";
let newStr = str.replace("Linda","Micheal")
//output: Micheal is a self-taught developer.Linda will rule the world
let newStr = str.replaceAll("Linda","Micheal")
//output: Micheal is a self-taught developer.Micheal will rule the world
The numeric separator simply improves the readability of large numbers by using the underscore (_) character to separate number groups, just like you use commas to separate numbers in writing. Consider the number 1200044555. At first glance, itβs quite difficult to decipher that this number is 1.2 billion and something.
Example:
const billGatesNetWorth = 1_200_044_555;
Now this is much more readable. Note that this doesnβt have any performance benefits or affect equality. 1_200_044_555 is still equal to 1200044555.
Promise.anyPromise.any([promise1, promise2, promise3, ...]).then(....do something)
The Promise.any() method is a new promise method that takes in a series of promises and resolves to the value of the first promise to successfully resolve. In other words, the Promise.any resolves successfully if any of the promises resolve and rejects if all promises reject.
Example:
const promise1 = new Promise((resolve) => setTimeout((resolve) => resolve, 300, 'faster'); const promise2 = new Promise((reject) => setTimeout( (reject) =>reject, 100,"fastest") const promise3 = new Promise((resolve) => setTimeout( (resolve) => resolve,700,'fast'); const promises = [promise1, promise2, promise3]; Promise.any(promises).then((value)=>console.log(value)); //Output: faster
WeakRefconst weakRef = new WeakRef({
name:"Linda";
});
console.log(weakRef.deref().name)
//output: Linda
WeakRef is an advanced feature that should probably be avoided, according to the TC39 proposal notes. To understand what WeakRef does, you need to first understand the concepts of object referencing and garbage collection in JavaScript.
const obj = {}
When you create an object in JavaScript and assign it to a variable, the JavaScript engine running on a browser allocates a memory address that stores the object. On the other hand, the variable to which the object is assigned stores the memory address of the object and not the value of the object itself. So, you can say that obj holds a reference to the object assigned to it.
As objects are created and stored in memory, at some point, the browser may start to run out of memory and will need to free up memory space. Garbage collection is the process through which the browser engine frees up memory space by deleting objects that are no longer referenced by any variable.
WeakRef creates a weak reference to the the object passed to it. This means that whenever the browser needs to run garbage collection, if the only reference to that object is from a WeakRef variable, the JavaScript engine can safely remove the object from memory and free up space. This could be ideal for WebSocket data because of their short lifespans.
A WeakRef is created with the new WeakRef constructor, and the value of the WeakRef variable can be accessed via the deRef method.
The new ES2021 features are already supported by recent versions of major browsers like Chrome 85, Firefox 79, and Safari 14. However, to enable your code to run in older browsers, you need to set up your project with the Babel complier.
Install the following packages:
npm install --save-dev @babel/core @babel/cli @babel/preset-env npm install core-js
Create a babel.config.json file at the root of your project:
{
"presets": [
[
"@babel/preset-env",
{
"useBuiltIns": "usage",
"corejs": {
"version": "3.8",
"proposals": true
}
}
]
]
}
The config above instructs Babel to use the env preset, which contains transforms for all the latest JavaScript features that have made it to stage four of the TC39 proposal process. It also instructs Babel to retrieve polyfills when needed from core JS.
Create a .browserlistrc file at the root of your project to specify the target browsers for Babel to transform code in:
defaults maintained node versions
The defaults query instructs Babel to transform and polyfill code only for:
maintained node versions states that Babel should transform and polyfill code for all Node versions that are still maintained by the Node.js foundation.
Now, you can run:
./node_modules/.bin/babel src --out-dir lib
This will parse and transform all your JavaScript files in the src directory into code suitable for older browsers (as specified by your .browserlistrc file) and output each file to the lib directory.
N.B., if youβre using a toolchain like Create React App or vue-cli, these configurations are already abstracted.
And thatβs it. Youβre good to go. Go and start using ES2021 today!
Debugging code is always a tedious task. But the more you understand your errors, the easier it is to fix them.
LogRocket allows you to understand these errors in new and unique ways. Our frontend monitoring solution tracks user engagement with your JavaScript frontends to give you the ability to see exactly what the user did that led to an error.
π LogRocket Dashboard Free Trial BannerLogRocket records console logs, page load times, stack traces, slow network requests/responses with headers + bodies, browser metadata, and custom logs. Understanding the impact of your JavaScript code will never be easier!
TSRX adds first-class control flow, conditional hooks, and scoped styles to React via a TypeScript compiler extension β no new framework required.
Learn how to build a full React Native auth system using Better Auth and Expo β with email/password login, Google OAuth, session persistence, and protected routes.
Compare the top AI development tools and models of June 2026. View updated rankings, feature breakdowns, and find the best fit for you.
Learn how Bloom filters reduce database lookups for username availability checks while preserving correctness at scale.
Would you be interested in joining LogRocket's developer community?
Join LogRocketβs Content Advisory Board. Youβll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.
Sign up now