What new features to expect ?
By: Mihai Dita
Tags: JavaScript, Javascript Tips, Programming, Javascript Development, Web Development

Image Credit: YouTube

What new features to expect ?

▹ replaceAll()

JavaScript has already a method named replace() . This method is used to replace a string with another value of type string. The replace() method will only replace the the first occurrence. We can use RegExr in order to replace everything or now we can use the replaceAll() function.

const p = 'The quick brown fox jumps over the lazy dog. If the dog reacted, was it really lazy?'; const regex = /dog/gi; console.log(p.replaceAll(regex, 'ferret'));

// expected output: "The quick brown fox jumps over the lazy ferret. If the ferret reacted, was it really lazy?" console.log(p.replaceAll('dog', 'monkey'));

// expected output: "The quick brown fox jumps over the lazy monkey. If the monkey reacted, was it really lazy?"

▹ Private Accessors

By appending # to the function name now we have private accessor functions.

// Private accessor

get #age() { return 42 }

set #age(value) {}

▹ Private Methods

Private method names starts with # . These methods are only available inside the class where it is defined.

class Car { // Private #setType() { console.log("set car type method"); } // Public show() { this.#setType(); } } const car = new Car(); car.show(); // "I am Private"; car.setType(); // TypeError: personObj.setType is not a function

▹ WeakRef

A WeakRef object contains a weak reference to an object, which is called its target or referent. A weak reference to an object is a reference that does not prevent the object from being reclaimed by the garbage collector. In contrast, a normal (or strong) reference keeps an object in memory.

When an object no longer has any strong references to it, the JavaScript engine's garbage collector may destroy the object and reclaim its memory. If that happens, you can't get the object from a weak reference anymore.

const callback = () => {

const aBigObj = new WeakRef({ name: "Test" }); console.log(aBigObj.deref().name);}



(async function(){

await new Promise((resolve) => {

setTimeout(() => {

callback(); // Guaranteed to print "Test"

resolve();

}, 2000);

});



await new Promise((resolve) => {

setTimeout(() => {

callback(); // No Gaurantee that "Test" is printed

resolve();

}, 5000);

});

})();

▹ Finalizers

A FinalizationRegistry object lets you request a callback when an object is garbage-collected. FinalizationRegistry provides a way to request that a cleanup callback get called at some point when an object registered with the registry has been reclaimed.

You create the registry passing in the callback:

const registry = new FinalizationRegistry(heldValue => {

// ....

});

Then you register any objects you want a cleanup callback for by calling the register method, passing in the object and a *held value* for it:

registry.register(theObject, "some value");

▹ Promise.any()

Promise.any() resolves if any of the provided promises is resolved. If no promises fulfill, then the returned promises is rejected with an AggregatorError .

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"

▹ AggregateError

An AggregateError exception is thrown by Promise.any() when none of the promises are resolved.

Promise.any([

Promise.reject(new Error("some error")),

]).catch(e => {

console.log(e instanceof AggregateError); // true

console.log(e.message); // "All Promises rejected"

console.log(e.name); // "AggregateError"

console.log(e.errors); // [ Error: "some error" ]

});

▹ Logical Assignment Operator

Some of the logical operations are && , || and ?? .Here we combine these operators with assignment.

const a;

const b = a ?? 5;

console.log(b); // 5 const x = 1;

const y = 2;

x ||= y;

console.log(x); // 1 const x = 1;

const y = 2;

x &&= y;

console.log(x); // 2

▹ Numeric separators

This feature allows us to make numeric literals more readable by adding visual separation between digits. Here is a link with more examples.

console.log(1000000); // 1000000 console.log(1_000_000); // 1_000_000 console.log(1_019_436_871.42); // 1019436871.42

Promise.allSettled()

Promise.allSettled() runs all promises regardless of rejection of any promises. Now we can create a new Promise that contains all the promises and the data of each.

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"

String.prototype.matchAll()

This one is very similar to replace() and replaceAll() . We already have match() available in JavaScript. With matchAll() we can access an iterator that contains all the results matching our string value.

const regexp = /t(e)(st(\d?))/g; const str = 'test1test2';

const array = [...str.matchAll(regexp)]; console.log(array[0]);

// expected output: Array ["test1", "e", "st1", "1"] console.log(array[1]);

// expected output: Array ["test2", "e", "st2", "2"]

Optional Chaining Operator

The optional chaining operator allow us to read the value of a property without having to directly validate the each reference in the chain. The expression short circuits with a return value of undefined .

This way is very easy to write and read the code and you don’t have to do extra work when there is no guarantee as to which properties are required.

const adventurer = {

name: 'Alice',

cat: {

name: 'Dinah'

}

}; const dogName = adventurer.dog?.name;

console.log(dogName);

// expected output: undefined console.log(adventurer.someNonExistentMethod?.());

// expected output: undefined

Dynamic Import 🔥

Dynamic import() introduces a new function-like form of import that caters to those use cases. import(moduleSpecifier) returns a promise for the module namespace object of the requested module, which is created after fetching, instantiating, and evaluating all of the module’s dependencies, as well as the module itself.

We can use async/await instead of the then based callback style because import returns a promise. We can use it with lazy loading.

⚠️ Although import() looks like a function call, it is specified as syntax that just happens to use parentheses (similar to super() ). That means that import doesn’t inherit from Function.prototype so you cannot call or apply it.

Consider the following module, located at ./utils.mjs :

// Default export

export default () => {

console.log('Hi from the default export!');

};



// Named export `doStuff`

export const doStuff = () => {

console.log('Doing stuff…');

};

Here’s how to dynamically import and use the ./utils.mjs module:

<script type="module">

(async () => {

const moduleSpecifier = './utils.mjs';

const module = await import(moduleSpecifier)

module.default();

// → logs 'Hi from the default export!'

module.doStuff();

// → logs 'Doing stuff…'

})();

</script>

BigInt

BigInt is a special numeric type that provides support for integers of arbitrary length. The BigInt can be used by adding n to the end of an integer or by calling the function BigInt that creates bigints from strings, numbers etc. We can’t mix bigints and regular numbers, if needed we should explicitly convert them. BigInt represents a number that is larger than 2^(53) –1 .

const bigInt = 123456789123456789n;

console.log(bigInt +1n);

//9007199254740992n console.log(bigInt +10n);

//9007199254741001n console.log(bigInt +100n);

//9007199254741001n console.log(bigInt +10);

//Error: Uncaught TypeError: Cannot mix BigInt and other types, use explicit conversions

Conclusion

JavaScript is always providing new ways and features to make the code and developers more productive and efficient. It’s very important as a developer to stay up to date with the new features that are released by your favorite programming language. I hope you liked the article and learned something interesting.