New ES2020 Features — Strings, Numbers, and This

John Au-Yeung - Feb 2 '20 - - Dev Community

Subscribe to my email list now at http://jauyeung.net/subscribe/

Follow me on Twitter at https://twitter.com/AuMayeung

Many more articles at https://medium.com/@hohanga

Even more articles at http://thewebdev.info/

Since 2015, the JavaScript is evolving fast with lots of new features coming out in each iteration.

New versions of the JavaScript language specification has been updated almost yearly, with new language feature proposal being finalized faster than ever.

This means that new features are getting incorporated into modern browsers and other JavaScript run-time engines like Node.js at a pace that we haven’t seen before.

In 2019, there are many new features that are in the ‘Stage 3’ phase, which means that it’s very close to being finalized and browsers are getting support for these features now.

If we want to use them for production code, we can use something like Babel to transpile them to older versions of JavaScript so they can be used in older browsers like Internet Explorer if needed.

In this article, we’ll look at the matchAll method, numeric separators, and the globalThis object to get the global object in all environments.

String.matchAll()

In the current version of the JavaScript, there’s no string method that can be used to search for all occurrences of a string along with the capturing groups.

To search for all instances of a string, we have to write our own regular expression and use the match method to search for the substring we want to search for.

For example, we can use the match method with our own regular expression passed in to search for all instances of a string like with the following code:

const str = 'foo bar foo';  
const matches = str.match(/foo/g);  
console.log(matches);

When we run the code above, we should get:

[  
  "foo",  
  "foo"  
]

The match method gets us an array of all the matches of a string according to a regular expression. Note that we have the g flag at the end of the regular expression literal. Otherwise, only the first match will be returned. Capturing group matches aren’t included when then the g flag is included.

Now we have another method called matchAll which very similar to match .

However, it returns an iterator that’s not restartable so that we can loop through the iterator returned by the matchAll method to get all the matches that were found.

It also takes in a regular expression and converts any non-regular expression object to a regular expression with the RegExp constructor.

Since it returns an iterator, we can use the spread operator, for...of loop and the Array.from method with it.

Another difference from the match method is that capturing group results are returned from the matchAll method, but not the match method.

If we use match like in the following code:

const str = 'foo bar foo foobar foofoobarbarbar foobarbar';  
const matches = str.match(/foo(bar)+/g);

We get:

[  
  "foobar",  
  "foobarbarbar",  
  "foobarbar"  
]

If we use matchAll like in the following code instead:

const str = 'foo bar foo foobar foofoobarbarbar foobarbar';  
const matches2 = str.matchAll(/foo(bar)+/g);

We get:

[  
  [  
    "foobar",  
    "bar"  
  ],  
  [  
    "foobarbarbar",  
    "bar"  
  ],  
  [  
    "foobarbar",  
    "bar"  
  ]  
]

As we can see, the capturing group (bar) is returned with every result with matchAll, but it isn’t returned with match with the g flag in the regular expression.

Also, another important difference is that the iterator returned by the matchAll method isn’t restartable. Once the values returned from the iterator are exhausted, then we have to call the method again to create a new iterator if we want the results again.

Numeric Separators

In earlier versions of JavaScript, read long numbers is a pain because there's nothing separating the numbers.

This means it’s almost impossible to tell how many digits are in big numbers from the human eye.

Now JavaScript has added digit separators for numbers to group them into smaller groups of digits with an underscore.

For example, we can use them as we do in the code below:

const x = 1_000_000_000_000

Then x would show 1000000000000 if we run console.log on it. It also works for decimal numbers:

const x = 1_363_372_373.378_473

Then x would show 1363372373.378473 if we run console.log on it. We don’t have to group digits in groups of 3. It can be grouped in whatever way we like, so if we have:

const x = 37378_44748

We get 3737844748 from the console.log of x if we run that. It also works for other bases like binary, hexadecimal or octal numbers. For example, we can write:

const binary = 0b111_111_111;  
const bytes = 0b1111111_11111111_1111111;  
const hex = 0xFAB_F00D;

The only catch is that we can’t use the underscore in number strings if we want to pass them into the Number or parseInt functions. If we write Number(‘123_456’) then we get NaN . If we run parseInt(‘123_456’) then we get 123. As we can see, they’re both incorrect. This means that we should sticky to number literals when using digit separators.

globalThis

The latest version of JavaScript also has the globalThis variable. This lets us get the true global object of an application rather than relying on the this object, which may change according to the context that it’s in. For example, if we run the following code:

console.log(globalThis);
function foo() {  
  console.log(globalThis)  
}  
new foo();

We can see that both console.log output the window object, which is the object that has the things that are part of the browser tab.

If we console.log the this keyword instead of globalThis in the foo function if we create a new instance of foo with the new keyword, we wouldn’t get the window object, instead we would get the foo function.

For example, if we replaced globalThis with the this keyword like in the code below:

console.log(this);
function foo() {  
  console.log(this)  
}  
new foo();

We would get the window object in the first console.log , but the console.log inside the foo function would get us the foo constructor instead. Other environments like web or service workers, self would be a global object.

In Node.js, the global object is called global . globalThis works in all environments so that we can use it for accessing the true global object.

It works in the latest versions of many browsers and the latest version of Node.js.

It’s guaranteed to work in both window and non-window contexts. It works by referencing the Proxy around the actual global object which we can’t access directly.

Conclusion

In the current version of the JavaScript, there are no string methods that can be used to search for all occurrences of a string along with the capturing groups.

With the matchAll method, we can all the matches and get all the capturing groups. In earlier versions of JavaScript, read long numbers is a pain because there's nothing separating the numbers.

This means it’s almost impossible to tell how many digits are in big numbers from the human eye.

Now JavaScript has added digit separators for numbers to group them into smaller groups of digits with an underscore.

We can group it however we like it with the separator. The latest version of JavaScript also has the globalThis method.

This lets us get the true global object of an application rather than relying on the this object, which may change according to the context that it’s in.

It also works in both window and non-window contexts so that run-time environments like Node.js can also use globalThis .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .