5 ES2019 features you can use today
Tags: es10
Published: 2019-07-08 20:19:57

---
title: 5 ES2019 features you can use today
published: true
tags: es10
canonical_url: https://blog.logrocket.com/5-es2019-features-you-can-use-today/
---

![](https://thepracticaldev.s3.amazonaws.com/i/puo867luzzwz9rxezvr7.jpg)

ECMAScript 2015, also known as ES6, was a major release that took six years to finalize. Since then, Technical Committee 39 (TC39), the body in charge of developing the ECMAScript standard, has been releasing a new edition of the standard every year. This annual release cycle has streamlined the process and made new features rapidly available, which the JavaScript community has welcomed.

This year, ECMAScript 2019 (or ES2019 for short) will be released. The new features include `Object.fromEntries()`, `trimStart()`, `trimEnd()`, `flat()`, `flatMap()`, description property for symbol objects, optional catch binding, and more.

The good news is that these features have already been implemented in the latest versions of Firefox and Chrome, and they can also be transpiled so that older browsers are able to process them. In this post, we will take a good look at these features and see how they upgrade the language.

[![LogRocket Free Trial Banner](https://i0.wp.com/blog.logrocket.com/wp-content/uploads/2017/03/f760c-1gpjapknnuyhu8esa3z0jga.png?resize=1200%2C280&ssl=1)](https://logrocket.com/signup/)

## 1. Object.fromEntries()

Transforming data from one format to another is very common in JavaScript. To facilitate the conversion of objects into arrays, ES2017 introduced the `Object.entries()` method. This method takes an object as an argument and returns an array of the object’s own enumerable string-keyed property pairs in the form of `[key, value]`. For example:

```jsx
const obj = {one: 1, two: 2, three: 3};

console.log(Object.entries(obj));    
// => [["one", 1], ["two", 2], ["three", 3]]
```

But what if we wanted to do the opposite and convert a list of key-value pairs into an object? Some programming languages, such as Python, provide the `dict()` function for this purpose. There’s also the `_.fromPairs` function in Underscore.js and Lodash.

ES2019 aims to bring a similar feature to JavaScript by introducing the `Object.fromEntries() method`. This static method allows you to easily transform a list of key-value pairs into an object:

```jsx
const myArray = [['one', 1], ['two', 2], ['three', 3]];
const obj = Object.fromEntries(myArray);

console.log(obj);    // => {one: 1, two: 2, three: 3}
```

As you can see, `Object.fromEntries()` is simply the reverse of `Object.entries()`. While it was previously possible to achieve the same result, it wasn’t very straightforward:

```jsx
const myArray = [['one', 1], ['two', 2], ['three', 3]];
const obj = Array.from(myArray).reduce((acc, [key, val]) => Object.assign(acc, {[key]: val}), {});

console.log(obj);    // => {one: 1, two: 2, three: 3}
```

Keep in mind that the argument passed to `Object.fromEntries()`can be any object that implements the iterable protocol as long as it returns a two-element, array-like object.

For example, in the following code, `Object.fromEntries()` takes a Map object as an argument and creates a new object whose keys and corresponding values are given by the pairs in the Map:

```jsx
const map = new Map();
map.set('one', 1);
map.set('two', 2);

const obj = Object.fromEntries(map);

console.log(obj);    // => {one: 1, two: 2}
```

The `Object.fromEntries()` method is also very useful for transforming objects. Consider the following code:

```jsx
const obj = {a: 4, b: 9, c: 16};

// convert the object into an array
const arr = Object.entries(obj);

// get the square root of the numbers
const map = arr.map(([key, val]) => [key, Math.sqrt(val)]);

// convert the array back to an object
const obj2 = Object.fromEntries(map);

console.log(obj2);  // => {a: 2, b: 3, c: 4}
```

This code converts values in an object into their square root. To do that, it first converts the object into an array, then uses the `map()` method to get the square root of values in the array. The result is an array of arrays that can be converted back to an object.

Another situation in which `Object.fromEntries()` comes in handy is when working with the query string of a URL, as shown in this example:

```jsx
const paramsString = 'param1=foo&param2=baz';
const searchParams = new URLSearchParams(paramsString);

Object.fromEntries(searchParams);    // => {param1: "foo", param2: "baz"}
```

In this code, a query string is passed to the `URLSearchParams()` constructor. Then the return value, which is a `URLSearchParams` object instance, is passed to the `Object.fromEntries()` method. The result is an object containing each parameter as a property.

The `Object.fromEntries()` method is currently a stage 4 proposal, which means it’s ready for inclusion in the ES2019 standard.

## 2. trimStart() and trimEnd()

The `trimStart()` and `trimEnd()` methods are technically the same as `trimLeft()` and `trimRight()`. These methods are currently stage 4 proposals and will be added to the specification for consistency with `padStart()` and `padEnd()`. Let’s look at some examples:

```jsx
const str = "   string   ";

// es2019
console.log(str.trimStart());    // => "string   "
console.log(str.trimEnd());      // => "   string"

// the same as
console.log(str.trimLeft());     // => "string   "
console.log(str.trimRight());    // => "   string"
```

For web compatibility, `trimLeft()` and `trimRight()` will remain as aliases for `trimStart()` and `trimEnd()`.

## 3. flat() and flatMap()

The `flat()` method enables you to easily concatenate all sub-array elements of an array. Consider the following example:

```jsx
const arr = ['a', 'b', ['c', 'd']];
const flattened = arr.flat();

console.log(flattened);    // => ["a", "b", "c", "d"]
```

Previously, you’d have to use `reduce()` or `concat()` to get a flat array:

```jsx
const arr = ['a', 'b', ['c', 'd']];
const flattened = [].concat.apply([], arr);

// or
// const flattened =  [].concat(...arr);

console.log(flattened);    // => ["a", "b", "c", "d"]
```

Note that if there are any empty slots in the provided array, they will be discarded:

```jsx
const arr = ['a', , , 'b', ['c', 'd']];
const flattened = arr.flat();

console.log(flattened);    // => ["a", "b", "c", "d"]
```

`flat()` also accepts an optional argument that specifies the number of levels a nested array should be flattened. If no argument is provided, the default value of 1 will be used:

```jsx
const arr = [10, [20, [30]]];

console.log(arr.flat());     // => [10, 20, [30]]
console.log(arr.flat(1));    // => [10, 20, [30]]
console.log(arr.flat(2));    // => [10, 20, 30]
```

The `flatMap()` method combines `map()` and `flat()` into one method. It first creates a new array with the return value of a provided function and then concatenates all sub-array elements of the array. An example should make this clearer:

```jsx
const arr = [4.25, 19.99, 25.5];

console.log(arr.map(value => [Math.round(value)]));    
// => [[4], [20], [26]]

console.log(arr.flatMap(value => [Math.round(value)]));    
// => [4, 20, 26]
```

The depth level that the array will be flattened is 1. If you want to remove an item from the result, simply return an empty array:

```jsx
const arr = [[7.1], [8.1], [9.1], [10.1], [11.1]];

// do not include items bigger than 9
arr.flatMap(value => {
  if (value >= 10) {
    return [];
  } else {
    return Math.round(value);
  }
});  

// returns:
// => [7, 8, 9]
```

In addition to the current element being processed, the callback function will also receive the index of the element and a reference to the array itself. The `flat()` and `flatMap()` methods are currently stage 4 proposals.

## 4. Description property for Symbol objects

When creating a Symbol, you can add a description to it for debugging purposes. Sometimes, it’s useful to be able to directly access the description in your code.

This ES2019 proposal adds a read-only description property to the Symbol object, which returns a string containing the description of the Symbol. Here are some examples:

```jsx
let sym = Symbol('foo');
console.log(sym.description);    // => foo

sym = Symbol();
console.log(sym.description);    // => undefined

// create a global symbol
sym = Symbol.for('bar');
console.log(sym.description);    // => bar
```

## 5. Optional catch binding

The catch binding in a `try … catch` statement would not always be used. Consider the following code:

```jsx
try {
  // use a feature that the browser might not have implemented
} catch (unused) {
  // fall back to an already implemented feature 
}
```

There is no use for the catch binding in this code. However, it still should be used to avoid a `SyntaxError`. This proposal makes a small change to the ECMAScript specification that allows you to omit the catch binding and its surrounding parentheses:

```jsx
try {
  // use a feature that the browser might not have implemented
} catch {
  // do something that doesn’t care about the value thrown
}
```

## Bonus: ES2020 String.prototype.matchAll

The `matchAll()` method is a stage 4 ES2020 proposal that returns an iterator object for all matches — including capturing groups — against a regular expression.

For consistency with the `match()` method, TC39 selected “matchAll” over other suggested names such as “matches” or Ruby’s “scan.” Let’s look at a simple example:

```jsx
const re = /(Dr\. )\w+/g;
const str = 'Dr. Smith and Dr. Anderson';
const matches = str.matchAll(re);

for (const match of matches) {
  console.log(match);
}

// logs:
// => ["Dr. Smith", "Dr. ", index: 0, input: "Dr. Smith and Dr. Anderson", groups: undefined]
// => ["Dr. Anderson", "Dr. ", index: 14, input: "Dr. Smith and Dr. Anderson", groups: undefined]
```

The capturing group in this regular expression matches the characters “Dr” followed by a dot and a space. `\w+` matches any word character one and more times. And the `g` flag instructs the engine to search for the pattern throughout the string.

Previously, you’d have to use the `exec()` method in a loop to achieve the same result, which wasn’t very efficient:

```jsx
const re = /(Dr\.) \w+/g;
const str = 'Dr. Smith and Dr. Anderson';
let matches;

while ((matches = re.exec(str)) !== null) {
  console.log(matches);
}

// logs:
// => ["Dr. Smith", "Dr.", index: 0, input: "Dr. Smith and Dr. Anderson", groups: undefined]
// => ["Dr. Anderson", "Dr.", index: 14, input: "Dr. Smith and Dr. Anderson", groups: undefined]
```

It’s important to note that although the `match()` method can be used with the global flag `g` to access all matches, it doesn’t provide capturing groups or index position of the matches. Compare:

```jsx
const re = /page (\d+)/g;
const str = 'page 2 and page 10';

console.log(str.match(re));    
// => ["page 2", "page 10"]

console.log(...str.matchAll(re)); 
// => ["page 2", "2", index: 0, input: "page 2 and page 10", groups: undefined] 
// => ["page 10", "10", index: 11, input: "page 2 and page 10", groups: undefined]
```

## Wrapping up

In this post, we have taken a close look at several key features introduced in ES2019, including `Object.fromEntries()`, `trimStart()`, `trimEnd()`, `flat()`, `flatMap()`, description property for symbol objects, and optional catch binding.

Despite the fact that these features are not fully implemented by some browser vendors yet, you can still use them in your projects thanks to Babel and other JavaScript transpilers.

ECMAScript’s pace of development has stepped up in recent years, and new features are being introduced and implemented every so often, so be sure to check out the list of [finished proposals](https://github.com/tc39/proposals/blob/master/finished-proposals.md) to get updated on what’s new. Do you have some tips? Share them in the comments!
* * *
## Plug: [LogRocket](https://logrocket.com/signup/), a DVR for web apps

[![LogRocket Dashboard Free Trial Banner](https://i2.wp.com/blog.logrocket.com/wp-content/uploads/2017/03/1d0cd-1s_rmyo6nbrasp-xtvbaxfg.png?resize=1200%2C677&ssl=1)](https://logrocket.com/signup/)

[LogRocket](https://logrocket.com/signup/) is a frontend logging tool that lets you replay problems as if they happened in your own browser. Instead of guessing why errors happen, or asking users for screenshots and log dumps, LogRocket lets you replay the session to quickly understand what went wrong. It works perfectly with any app, regardless of framework, and has plugins to log additional context from Redux, Vuex, and @ngrx/store.

In addition to logging Redux actions and state, LogRocket records console logs, JavaScript errors, stacktraces, network requests/responses with headers + bodies, browser metadata, and custom logs. It also instruments the DOM to record the HTML and CSS on the page, recreating pixel-perfect videos of even the most complex single-page apps.

[Try it for free](https://logrocket.com/signup/).
* * *
The post [5 ES2019 features you can use today](https://blog.logrocket.com/5-es2019-features-you-can-use-today/) appeared first on [LogRocket Blog](https://blog.logrocket.com).