Useful features of ECMAScript 2019 reviewed
Tags: webdev, javascript, ecmascript
Published: 2019-08-06 13:45:17

First of all let me apologise for not writing as frequent as I would've liked. It's been a crazy busy couple of weeks and I had heaps of fun speaking at [DDD Perth 2019](https://dddperth.com/agenda?sessionId=00311b92-6c21-47a8-b8d2-af325581d6f9).

That taken care of, this time I thought let's go through the new features which are added into the [ECMAScript 2019 (aka ES2019 or ES10)](https://www.ecma-international.org/ecma-262/10.0/index.html), because they're super exciting and make our lives much easier 😎.

<!--more-->

## TLDR;

At a glance, this version adds a few built-in functions on `Array.prototype`, `flat` and `flatMap`. Then we have `Object.fromEntries` for directly turning the return value of `Object.entries` into a new _Object_.

We also have `trimStart` and `trimEnd` on `String.prototype` over the widely used non-standard versions `String.prototype.trimLeft` and `trimRight`.

Another exciting feature is optional `catch` binding parameters. In addition to those, there are some JSON improvements, addition of `Symbol.prototype.description` which allows you to specify a description for your symbol, `JSON.stringify` returns well-formed **UTF-8** regardless of input, and at last clarifying `Function.prototype.toString` by requiring that it either return the corresponding original source text or a standard placeholder.

So if you're ready let's dig in.

### `Array.prototype.{flat, flatMap}`

`flat()` is a new method which let's you create a one-dimensional array from a multi-dimensional one.

Imagine we have an array like below:

```js
const myArray = [1, 2, 3, [4, 5, 6, [7, 8, 9, [10, 11, 12]]]];
```

Prior to `flat` if you wanted to achieve this, you had to do something like this:

```js
const myNewArray = [].concat.apply([], myArray)
// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
```

Or:

```js
var myNewArray = myArray.reduce(
  function(prev,curr) {
    return prev.concat(curr)
  }
)
// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
```

With this new addition, it would be as simple as:

```js
var myNewArray = myArray.flat(4);
// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
```

You can also chain multiple calls:

```js
var myNewArray = myArray.flat().flat().flat().flat();
// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
```

The argument into the `flat` function just specifies how deep it should look into the array. If you're not sure how deep the array is, simply use `Infinity` as input:

```js
var myNewArray = myArray.flat(Infinity);
// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
```

And if you don't provide any input, by default it only goes one level deep:

```js
var myNewArray = myArray.flat(); 
// [1, 2, 3, 4, 5, 6, Array(4)];
```
<hr/>

`flatMap` on the other hand, allows you to map each element using a mapping function and then flattens the result into a new array. Think of it as chaining a `map` function with a single `flat`. However, it can be really helpful both in terms of usage and efficiency of execution.

```js
let myArray = [1, 2, 3, 4, 5];

let mappedArray = myArray.map(x => [x, x * 2]);
// [Array(2), Array(2), Array(2), Array(2), Array(2)]
// 0: (2)[1, 2]
// 1: (2)[2, 4]
// 2: (2)[3, 6]
// 3: (2)[4, 8]
// 4: (2)[5, 10]

let mappedFlattenedArr = mappedArray.flat();

// [1, 2, 2, 4, 3, 6, 4, 8, 5, 10]

let myNewArray = myArray.flatMap(v => [v, v * 2]);
// [1, 2, 2, 4, 3, 6, 4, 8, 5, 10]
```

### `String.prototype.{trimStart, .trimEnd}`

These methods are fairly obvious as to what they will do for us. Just keep in mind that we had `trimLeft` which will be replaced by `trimStart` and `trimRight` which will be replaced by `trimEnd`.

```js
let message = ' This is a string with white space around ';

message = message.trimStart();
// 'This is a string with white space around '

message = message.trimEnd();
// 'This is a string with white space around'
```

### `Object.fromEntries`

This method get an `Iterable` and transforms key-value pairs to an object. But let's see what is an `Iterable`:

>JavaScript supports a protocol by which objects such as arrays can be used by control structures such as `for`…`of` and the spread operator `...` to loop through data sequentially. This is referred to as the iterable and the data structures that support this functionality are called iterables. While JavaScript provides maps, arrays and sets with an iterable property from the get-go, plain objects do not have this by default.

To see this in action:

```js
let entries = new Map([["name", "john"], ["age", 22]]);

let newObj = Object.fromEntries(entries);
// { name: 'john', age: 22 }
```

A real life use case is when parsing query strings:

```js
let query = Object.fromEntries(new URLSearchParams('foo=bar&baz=qux'));

// { foo: 'bar', baz: 'qux' }
```

### Optional Catch Binding

Optional catch binding allows us to use `try/catch` without the `error` parameter inside the catch block.

Previously you had to use this syntax regardless of whether you cared about `err` or not, such as when you had to fall back to feature to support older browsers:

```js
try {
  // try to use a web feature which may not be implemented
} catch (unused) {
  // fall back to a less desirable web feature with broader support
}
```

With `ES2019` you can do:

```js
try {
  // ...
} catch {
  // ...
}
```

### `Symbol.description`

This new read-only description property is a string returning the optional description of `Symbol` objects. This method is encouraged to be used instead of `Symbol.prototype.toString`
where it wasn't obvious what will be returned.

```js
let description = 'This symbol represents an emoji 😁';

let mySym = Symbol(description);
// Symbol('This symbol represents an emoji 😁')

console.log(mySym.description);
'This symbol represents an emoji 😁'
```

### `Function.toString`

This method is a really useful one which returns the source code of a function. Imagine doing a troubleshooting on a block of code which is using a third party function. This can potentially help you to see the implementation (given it's got source maps).

```js
function myFn(emoji) {
  let msg = `${emoji} is hellav an emoji`;
  console.log(msg);
}

console.log(myFn.toString());

// "function myFn(emoji) {
//   let msg = `${emoji} is hellav an emoji`;
//   console.log(msg);
// }"
```

Of course this doesn't work for everything. If we try it for `map` function on array:

```js
Array.prototype.map.toString();

// "function map() { [native code] }"
```

Since the implementation is not written in JavaScript, it will just show you that this function is written in native code.

### `JSON.stringify`

The team have done an improvement with **Unicode** characters and now this method can't return malformed data.

```js
// Non-BMP characters still serialize to surrogate pairs.
JSON.stringify('𝌆')
// → '"𝌆"'
JSON.stringify('\uD834\uDF06')
// → '"𝌆"'

// Unpaired surrogate code units will serialize to escape sequences.
JSON.stringify('\uDF06\uD834')
// → '"\\udf06\\ud834"'
JSON.stringify('\uDEAD')
// → '"\\udead"'
```

### `Array.sort` Stability

The team has decided to change the sort implementation so that it would be stable (that is, elements that compare equal must remain in their original order).

```js
const grades = [
  { topic: 'math', grade: 10 },
  { topic: 'literacy', grade: 10 },
  { topic: 'chemical', grade: 13 },
  { topic: 'geography', grade: 12 },
  { topic: 'modern history', grade: 12 },
  { topic: 'art', grade: 13 },
  { topic: 'computer basics', grade: 14 },
  { topic: 'algebra', grade: 14 },
];

grades.sort(a, b => a.grade - b.grade);

// 0: {topic: "math", grade: 10}
// 1: {topic: "literacy", grade: 10}
// 2: {topic: "geography", grade: 12}
// 3: {topic: "modern history", grade: 12}
// 4: {topic: "chemical", grade: 13}
// 5: {topic: "art", grade: 13}
// 6: {topic: "computer basics", grade: 14}
// 7: {topic: "algebra", grade: 14}
```

### Summary

In general JavaScript is moving in the right direction for helping developers write more stable, reliable and consistent code. You can find more information on their [GitHub repo here](https://github.com/tc39/proposals).

Hope to see more awesome features in JavaScript and see you soon with another article.