JavaScript is one of the most popular programming languages due to its agility, simplicity and capabilities in building powerful applications. One of the reasons why JavaScript continues to be popular is because new features are constantly being developed to improve its capability and efficiency. This year, there are five new features that all javascript users should be looking forward to adopting. While some of these features were available to users in the previous years, they were still in the test stage and were officially published at the start of 2021. These features include:
Addition of String.replaceAll(" "," ")
This new feature will make it easier to replace a character throughout the string without using the global declaration ‘/g’. Before it’s introduction, developers had to use String.replace() repetitively or add a global declaration for all the characters to be replaced.
const mystring= 'Hi there';
console.log(mystring.replaceAll('E', 'e'));
//output: 'Hi thErE'
Promise.any()
This feature adds an extra way of handling promises and will make logic flow much easier. In operation, this method returns a promise which only resolves after the previous promise in the iterable is resolved or it rejects if all of the iterable promises are rejected.
The difference between Promise.any() and Promise.race() is that the first one’s focus on the promise that is settled first while the second focuses on the promise that resolves first.
The syntax is as follows: Promise.any(iterable)
Below is an example of how to use Promise.any();
const firstpromise = new Promise((resolve, reject) => {
setTimeout(reject, 200, '1st promise rejected');
});
const secondpromise = new Promise((resolve, reject) => {
setTimeout(resolve, 400, '2nd promise resolved at 400 ms');
});
const thirdpromise = new Promise((resolve, reject) => {
setTimeout(resolve, 800, '3rd promise resolved at 900 ms');
});
(async () => {
try {
let myvalue = await Promise.any([firstpromise, secondpromise, thirdpromise]);
console.log(myvalue);
} catch (error) {
console.log(error);
}
})();
//Output - "At 400 ms secondpromise resolved"
Logical Assignment Operators
This is a convenience feature that will allow for the optimization of the code. This will complement the operators ||, ?? and &&. These operators help in creating logic in a workflow but are limited. With the logical assignment operators the ability to stop at an operator assign another value without having to kill the process or logic is now possible.
Below is an example of a logical assignment operator.
const h1 = false;
h1 ||=20
console.log(h1) //output 20
let h2 = true;
h2 ||= 20
console.log(h2) //output true
Numerical Separators
Although this new feature doesn’t add new capability to Javascript, it does fix a common problem faced by many developers. As simple as it may seem, the use of a separator becomes very important while dealing with large numbers which in a non-programming environment is simplified the use of a comma. This feature uses the _ character, after every three digits to help the developer easily understand the number without having to count in 3s from the end.
For example:
console.log(587896589852)
This is not an easy number to understand. With the new numerical separator, this number can now be written as:
console.log(587_896_589_852)
WeakRef and Finalizers
These two features are applied in garbage collection. They are recommended for experts only, and even for them, it is recommended to use when it's absolutely necessary. Javascript developers should not view these features as being a new addition that can make your apps better. Their application is rare and also very complicated. If not well implemented they can cause the memory allowed for the application to be reduced or lead to loss of some objects during memory optimization. WeakRef is used to resolve issues that arise when you have an object that is taking a lot of memory and consuming a lot of the available resources. WeakRef creates a reference to such an object without having to force it to stay in memory. If garbage comes along, it can clean it up without destroying the reference.
Some more features that are still in trial stages and JavaScript developers can look forward to include:
Top Level await
This is a feature that orders resource importation within the body of the function to be executed. The top level ‘await’ allows the developers to use the await keyword outside of the async function. Top level ‘await’ resources cause body evaluation by other modules importing them to wait. This feature allows the module system to control promises flow and coordination amongst these promises.
import { square, diagonal } from './library.js';
let sOutput;
let dOutput;
export default (async () => {
await delay(2000);
sOutput = square(12);
dOutput = diagonal(4, 3);
return {sOutput,dOutput};
})();
function delay(Inms) {
return new Promise(resolve => {
setTimeout(() => {
resolve(console.log('❤️'));
}, Inms);
});
}
//------ main.js ------
import promise from './middleware.js';
promise.then(({sOutput,dOutput})=>{
console.log(sOutput); // 144
console.log(dOutput); // 5
console.log('From Main');
setTimeout(() => console.log(sOutput), 2500);// 144
setTimeout(() => console.log(dOutput), 2500);// 5
})
Module blocks
Module blocks provide an efficient way of importing modules by providing an easy reference. They are module contents syntax that is later imported. The biggest advantage of using module blocks is that they can be used to import other modules fetched from the network.
‘sensitive’ and ‘hide source’
These are indicators that can be used by the developer to make some implementation details private. This is especially important when a developer wants to refactor their code without letting the user into the exact implementation process. It’ll provide a necessary layer of security for security-sensitive codes.
function foo() {
const m = () => {};
const n = () => {
"hide source";
class Z {
q() {}
}
};
}
Partial application
This willow developers to partially apply their argument list in calling an expression by making use of an argument's placeholder. This will introduce a new syntax ‘?’ It will make it possible for a developer to fix several arguments to a function and return a different function. Code example without partial application:
function add(m, n) { return m + n; }
const addOne = add.bind(null, 1);
addOne(5); // 6
const addTwelve = x => add(x, 12);
addTwelve(2); // 14
const newScore = player.score
|> _ => add(7, _)
|> _ => clamp(0, 100, _);
Code example with a partial function:
const addOne = add(1, ?); // apply from the left
addOne(5); // 6
const addTwelve = add(?, 12); // apply from the right
addTwelve(2); // 14
let newScore = player.score
|> add(7, ?)
|> clamp(0, 100, ?);
const Diagnostics = {
unexpected_token: `Unexpected token: ${?}`,
name_not_found: `'${?}' not found.`
};
Diagnostics.name_not_found("foo");
Pipeline operator
This new feature will make it more efficient to chain several functions together. It will introduce a new syntax ‘|>’. Code example without pipeline operator:
function sayTwice (mystring) {
return mystring + ", " + mystring;
}
function capital (mystring) {
return mystring[0].toUpperCase() + mystring.substring(1);
}
function excl(mystring) {
return mystring + '!';
}
With the pipeline operator, the above code can be written as:
const result1 = excl(capit(sayTwice("world")));
result1 //=> "World, world!"
let result2 = "world"
|> sayTwice
|> capital
|> excl;
result2 //=> "World, world!"
Conclusion
Apart from the last feature above, all the other features will be very important to Javascript developers. The efficiency that String.replaceAll(), Promise.any() and logical assignment operators will not only make it easier to run complex logic more efficiently but will also ensure the code is neat. The numerical separator will make it easier to use numerals in javascript while reducing the chances of mistakes made while using numerals beyond thousands. WeakRef and Finalizers will make the complex project’s memory efficient and ensure resources are freed up for other processes in the application. Top level ‘await’, module blocks, hide source, partial operator, and pipeline operator will also improve efficiency and the capability of Javascript applications. Before adding these features to the application, it is important that the developers take time to fully understand them.
References
ES2021 / ES12 New Features | Backbencher.dev
Why Should You Use Top-level Await in JavaScript? | by Mahdhi Rezvi | Bits and Pieces (bitsrc.io)