Javascript reach has increased from a web browser to all places of programming.

Node.js — Used for CLI and Server. Electron — Used for cross-platform desktop Apps. React native — Used for cross-platform mobile Apps. IoT — Low-cost IoT devices, now support javascript.

Recent updates to v8 engine have increased the performance a lot. The javascript parsing is 2x faster, promise on an avg is 11x faster on node version ≥11 from node version 8. The memory consumption as decreased -20%. So there is an improvement in performance and usability.

In this article, we will see some of the presents and purposed features that you can test in chrome browser (version ≥76) or Node.js(version ≥11) CLI.

Private Class field👇

Until ES6, we were not able to declare private properties directly. Yes there were ways like underscore convention ( _propertyName ), closures, symbols, or WeakMaps.

But now private class fields use a hash # prefix. Let’s learn it by an example.

class Test { a = 1; // .a is public

#b = 2; // .#b is private

static #c = 3; // .#c is private and static incB() {

this.#b++;

} } const testInstance = new Test(); // runs OK

testInstance.incB(); // error - private property cannot be modified outside class

testInstance.#b = 0;

Note: There’s no way to define private function as of now, although a TC39 stage 3: draft proposal suggests using a hash # prefix on names. 🤞

String.matchAll()👇

If I have a string, with a global regular expression which has many capturing groups, I often want to iterate through all groups. Currently, my options are the following:

String.prototype.match() with /g — If we use .match() with a regular expression whose flag /g is set, you get all full matches for it in an Array. String.prototype.split() — If we use a split string and regular expression to specify the separator and if it contains at least one capture group then .split() returns an Array in which the substrings are interleaved.

The issues with the above approach are that they only work if /g is set on regular expression and the property .lastIndex of a regular expression is changed each time a match happens. This makes using the same regular expression at multiple locations risky.

The matchAll() help resolve all above. Let’s check out the definition and usage

Given a string and a regular expression, .matchAll() returns all results matching a string against a regular expression, including capturing groups.

let regexp = /t(e)(st(\d?))/g;

let str = 'test1test2'; let array = [...str.matchAll(regexp)]; console.log(array[0]);

// expected output: Array ["test1", "e", "st1", "1"]

Note: .matchAll() returns an iterator, not a true restartable iterable. That is, once the result is exhausted, you need to call the method again and create a new iterator.

Numeric Separators👇

If you have struggled to read a long sequence of number, this is where your search end.

Numeric Separators allow the human eye to parse quickly, especially when there are lots of repeating digits:

1000000000000 -> 1_000_000_000_000

1019436871.42 -> 1_019_436_871.42

Now it’s easier to tell that the first number is a trillion, and the second number is in the order of 1 billion.

It also works on other bases, for example:

const fileSystemPermission = 0b111_111_000;

const bytes = 0b1111_10101011_11110000_00001101;

const words = 0xFAB_F00D;

You can also use the separator in the fractions and exponents:

const massOfElectronInKg = 9.109_383_56e-31;

const trillionInShortScale = 1e1_2;

Note: Parsing the _ separated integer can be tricky as Number('123_456') gives NAN whereas parseInt('123_456') gives 123 .

BigInt’s👇

BigInts are a new numeric primitive in JavaScript that can represent integers with precision larger than 2⁵³–1. With BigInts , you can safely store and operate on large integers even beyond the safe integer limit for Numbers .

BigInts correctly perform integer arithmetic without overflowing. Let’s understand by an example:-

const max = Number.MAX_SAFE_INTEGER;

// 9007199254740991

max+1;

// 9007199254740992

max+2;

// 9007199254740991

We can see that max + 1 produces the same result as max + 2 .

Any calculation on integers outside the safe integer range (i.e. from Number.MIN_SAFE_INTEGER to Number.MAX_SAFE_INTEGER ) potentially loses precision. For this reason, we can only rely on numeric integer values within the safe range.

Therefore, BigInts came to existence, BigInts can be created by adding the n suffix to any integer literal. For example, 123 becomes 123n or the global BigInt(number) function can be used to convert a Number into a BigInts.

Let’s revisit the above example with BigInt s

BigInt(Number.MAX_SAFE_INTEGER) + 2n;

// 9007199254740993n typeof 123n

// "bigint2"

Note: Numeric separators are especially helpful with BigInts, for eg: const massOfEarthInKg = 6_000_000_000_000_000_000_000_000n;

BigInts support the most common operators. Binary + , - , * , and ** all work as expected. / and % work, and round towards zero as needed.

(7 + 6 - 5) * 4 ** 3 / 2 % 3;

// → 1

(7n + 6n - 5n) * 4n ** 3n / 2n % 3n;

// → 1n

Note: One gotcha is that it’s not allowed to mix operations between BigInts and Numbers

Locale String with BigInt👇

The toLocaleString() method returns a string with a language-sensitive representation of the BigInt.

let bigint = 123456789123456789n; // German uses period for thousands

console.log(bigint.toLocaleString('de-DE'));

// → 123.456.789.123.456.789 // Arabic in most Arabic speaking countries uses Eastern Arabic digits

console.log(bigint.toLocaleString('ar-EG'));

// → ١٢٣٬٤٥٦٬٧٨٩٬١٢٣٬٤٥٦٬٧٨٩ // India uses thousands/lakh/crore separators

console.log(bigint.toLocaleString('en-IN'));

// → 1,23,45,67,89,12,34,56,789 // the nu extension key requests a numbering system, e.g. Chinese decimal

console.log(bigint.toLocaleString('zh-Hans-CN-u-nu-hanidec'));

// → 一二三,四五六,七八九,一二三,四五六,七八九 // when requesting a language that may not be supported, such as

// Balinese, include a fallback language, in this case Indonesian

console.log(bigint.toLocaleString(['ban', 'id']));

// → 123.456.789.123.456.789

globalThis Keyword👇

JavaScript’s variable scopes are nested and form a tree whose root is the global scope and the value of the this keyword is a reference to the object that “owns” the currently executing code or the function where its looked at.

To read more about this keyword and global scope read my below articles

Usually to figure out the global this we use a function like

const getGlobalThis = () => {



// in webworker or service worker

if (typeof self !== 'undefined') return self;



// in browser

if (typeof window !== 'undefined') return window;



// in Node.js

if (typeof global !== 'undefined') return global;



// Standalone javascript shell

if (typeof this !== 'undefined') return this;



throw new Error('Unable to locate global object');

}; const theGlobalThis = getGlobalThis();

The above function does not cover all cases when we need global this value.

In case of use strict the value of this is undefined When we form a bundle in the javascript it usually wraps under some code that might differ the global this. In Standalone javascript engine shell environment, the above code will not work

To solve the above problem globalThis keyword is introduced which returns global this object in any environment at any time.

Note: The global object is now considered a mistake that JavaScript can’t get rid of, due to backward compatibility. It affects performance negatively and is generally confusing.

Promise.allSettled()👇

If you are wondering what’s promise is in javascript then check out this — JavaScript Promises: an Introduction.

A little gist, a promise is JavaScript’s way of promising you that work will be done (or might fail if the work could not be completed).

The new method returns a promise that resolves after all of the given promises have settled i.e either resolved or rejected, with an array of objects that each 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"

This is different from the Promise.all as it rejects as soon as a promise within the iterable object rejected.

Below is the comparison of current supported promises method

Dynamic Import👇