We currently use the underscore prefix to denote that `_count` should not be used directly by the consumers of the class, but that’s just a convention — the privacy is not enforced by the language. Anyway, that’s what this class looks like using the old familiar class syntax. The new public class fields syntax allows us to simplify the class definition. The `_count` property is now nicely declared at the top of the class. We no longer need a constructor just to define some fields. Pretty neat! But, the `_count` property is still a public property in this particular example. We want to prevent direct access to that property. And that’s where private fields come in. So the new private fields syntax is similar to public fields, except you mark the fields as being private by using the `#` symbol. You can think of the hash as being as part of the field name.
This is more than just fancy syntax: private fields are actually private! This means they’re not accessible from outside the class body. When you try, you get a SyntaxError. Class field syntax is especially convenient when dealing with subclasses that introduce additional fields. Consider this `Animal` base class for example. To create a `Cat` subclass that introduces an additional instance property, you’d previously have to call `super()` to run the constructor of the `Animal` base class before creating this property. That’s a lot of boilerplate just to indicate that cats don’t like taking baths! Luckily, the class field syntax removes the need for the whole constructor, including the awkward `super` call. All it takes to add the class field is just that one line. Chrome supports both public and private class fields, and so does Node.
js. And more class features are coming soon! We’re working on adding support for private methods and private getters and setters. Another feature we previewed last year is String#matchAll, which is useful when dealing with regular expressions. It’s common to repeatedly apply the same regular expression on a string to get all the matches. And to some extent this is already possible today by using the String#match method. In this example we find all the words that consists of hexadecimal digits only, and then we log each match. However, this only gives you the substrings that match. Usually you don’t just want the substrings, you also want additional information such as the index of each substring or the capturing groups within each match. And it’s already possible to achieve that by writing your own loop and then keeping track of the match objects yourself, but it’s a little annoying and just not very convenient.
So instead of writing these numbers like this, you can now write them like this, grouping the digits per thousand. Now it’s easier to tell that the first number is in fact a trillion and the second number is in the order of a billion. This small feature helps improve readability for all kinds of numeric literals. Last year, this feature wasn’t supported anywhere yet. The details of the proposal were still being worked out. But since then, the open issues have been resolved, and browsers can now start implementing it. Numeric separators are already shipping in Chrome 75, and transpilers like Babel support them too. Speaking of numbers, we have some news about BigInt as well. Here’s a quick reminder why BigInt is useful. In this example we’re multiplying two numbers. Now, I’m no math genius, but this doesn’t look right to me. Looking at the least significant digits, 9 and 3, we know that the result of the multiplication should end in 7 (because 9 times 3 is 27) but instead the result ends in a bunch of zeros.
fromEntries. You may have used the Object.entries API before — that one has been around for a while. For each key-value pair in an object, it gives you an array where the first element is the key, and the second element is the value. And this is especially useful in combination with `for-of`, because you can then very elegantly iterate over all the key-value pairs in an object. Unfortunately, there’s no easy way to go from the entries result back to an equivalent object — until now! The new Object.fromEntries API performs the inverse of Object.entries. This makes it really easy to reconstruct an object based on its entries. Now why is this useful? Well, one common use case is transforming objects. You can now do this by iterating over the object’s entries, and then using array methods that you are probably already familiar with. In this example we’re filtering the object to only get keys of length 1, that is, we only want the keys `x` and `y` but not the key `abc`.
RelativeTimeFormat API can generate these phrases for you for each language you support. This code example creates a relative time formatter for the English language. We set the `numeric` option to `'auto'` to tell the formatter it can use phrases like “yesterday” instead of “one day ago”. The formatter recognizes several time units such as seconds, minutes, hours, days, months, quarters, and weeks. We pass it a number and a unit, and it returns a string that represents the relative time. And this doesn’t just work for English, but for other languages like Tamil as well. Previously developers had no choice but to implement such APIs themselves. One problem with implementing a localized relative time formatter is that you need a list of customary words or phrases such as “yesterday” or “last quarter” for each language you support.
One way to print the date range is to use the regular locale-unaware string formatting: you format the start date, you format the end date, and piece them together into a string. Here the second date’s month and year calendar fields are redundant — only the day provides new information. So instead, with the new `formatRange` method, we can display all the relevant fields and none of the repeating ones. The `formatRange` method is available behind a flag in Chrome, and we plan to ship it very soon. In the previous examples, you may have noticed the locale ID that we passed to the various Intl constructors, such as `'en'` for English. Intl.Locale offers a powerful mechanism to deal with such locales. It enables easily extracting locale-specific preferences, such as not only the language, but also the calendar, the numbering system, the hour cycle, the region, and so on. The Intl.Locale proposal is now available in Chrome and Node.
js. You can use a polyfill for other browsers. If you’ve used promises before, you might already be familiar with the lovely async/await syntax. Instead of chaining promise callbacks using `then`, you can nicely `await` the result of a promise. This syntax has been around for a while. However, `await` can only occur within an async function. There are use cases for wanting to use `await` at the top level, but currently this isn’t possible. One workaround is taking all your top- level code and wrapping it up in an async function that you then call. Another approach is to wrap your top-level code in an immediately-invoked async function expression. But a new proposal enables the use of `await` at the top-level, removing the need for these workarounds. The Chrome DevTools Console already wraps your input in an async function behind the scenes if the input contains `await`, so it looks like top-level `await` already works in the console. But that’s not because we implement the proposal — we don’t! The exact details of the top-level `await` proposal are still being worked out, and as such it’s still too early to implement it. It’s not currently supported everywhere.
In such a case, you could use Promise.all: you want to know when all promises are fulfilled, or as soon as one of them rejects. Promise.race is useful if you want to run multiple promises and either do something with the first successful result that comes in, in case one of the promises fulfills, or do something as soon as one of the promise rejects. That is: if one of the promises rejects, you want to preserve that rejection, and treat that error case separately. Here, we do exactly that: we kick off a computationally expensive task that might take a long time, but we race it against a promise that rejects after two seconds. Depending on the first promise to fulfill or reject, we either render the computer result, or the error message in two separate code paths. There was a top-level await in that example, by the way.
Now we don’t have to perform the expensive operation again for the same name. But there’s a problem: maps hold on to their keys and values strongly, so the image names and data can never be garbage-collected so this steadily increases memory and causes a memory leak. Note that using a WeakMap would not help here, as WeakMaps don’t support strings as keys. A new proposal makes it possible to solve the memory leak by creating a weak reference to the image and storing that in the cache instead of the image itself, so when the garbage collector realizes that it’s running out of memory, it can clean up some of the images. But there’s still a problem here: the map still holds on to the name strings forever, because those are the keys in the cache. Ideally those strings would be removed as well. The WeakRefs proposal has a solution for that as well. With the new `finalizationGroup` API, we can register a callback to run when the garbage collector zaps a registered object. So here, we register a callback to remove the keys from the cache when the image objects are garbage- collected.