JavaScript: What’s new in ES2019

As one of the most popular programming languages and the staple of web development, JavaScript is constantly evolving and with each iteration, it gets some fresh internal changes. Let’s check out some of the new proposed features of ES2019 that could soon find a way into our everyday code:

Array.flat()

You can now flatten nested arrays recursively up to a specified depth. The default value is 1 and if you want to go full depth use Infinity. This method does not modify the original array but creates a new one:

const arr1 = [1, 2, [3, 4]];
arr1.flat(); // [1, 2, 3, 4]

const arr2 = [1, 2, [3, 4, [5, 6]]];
arr2.flat(2); // [1, 2, 3, 4, 5, 6]

const arr3 = [1, 2, [3, 4, [5, 6, [7, 8]]]];
arr3.flat(Infinity); // [1, 2, 3, 4, 5, 6, 7, 8]

If you have an empty slot in your array it is going to be removed:

const arr4 = [1, 2, , 4, 5];
arr4.flat(); // [1, 2, 4, 5]

Array.flatMap()

A new method that combines the basic map function and then flattens the result to a depth of 1 with the new Array.flat() method:

const arr1 = [1, 2, 3];

arr1.map(x => [x * 4]); // [[4], [8], [12]]
arr1.flatMap(x => [x * 4]); // [4, 8, 12]

Another more useful example:

const sentence = ["This is a", "regular", "sentence"];

sentence.map(x => x.split(" ")); // [["This","is","a"],["regular"],["sentence"]]
sentence.flatMap(x => x.split(" ")); // ["This","is","a","regular", "sentence"]

String.trimStart() and String.trimEnd()

In addition to String.Trim() which removes whitespaces from both sides of a string there are now separate methods for only removing white spaces from each side:

const test = " hello ";

test.trim(); // "hello";
test.trimStart(); // "hello ";
test.trimEnd(); // " hello";

Object.fromEntries

A new method that transforms a list of key-value pairs into an object. It performs the reverse of an already familiar function Object.Entries which is used when transforming objects to arrays for their easier manipulation. After the transformation, you would be left with an array but now you can return the manipulated array back into an object. Let’s try with an example where we want to square the values of all of our object properties:

const obj = { prop1: 2, prop2: 10, prop3: 15 };

let array = Object.entries(obj); // [["prop1", 2], ["prop2", 10], ["prop3", 15]]

Let’s square the values of the new list of key-value pairs with a simple map:

array = array.map(([key, value]) => [key, Math.pow(value, 2)]); // [["prop1", 4], ["prop2", 100], ["prop3", 225]]

We’ve transformed the object values but we are left with an array and that is where Object.fromEntries comes in, transforming the array back to an object:

const newObj = Object.fromEntries(array); // {prop1: 4, prop2: 100, prop3: 225}

Optional Catch Binding

The new proposal allows you to completely omit the catch() parameter as there are a lot of cases where you don’t want to use it:

try {
  //...
} catch (er) {
  //handle error with parameter er
}

try {
  //...
} catch {
  //handle error without parameter
}

Symbol.description

You can now access the description property of a Symbol instead of using the toString() method:

const testSymbol = Symbol("Desc");

testSymbol.description; // "Desc"

Function.toString()

Calling toString() on a function now returns the function exactly as it was defined including whitespaces and comments. Before we had:

function /* foo comment */ foo() {}

foo.toString(); // "function foo() {}"

And now it’s:

foo.toString(); // "function /* foo comment */ foo() {}"

JSON.parse() improvements

The line separator (\u2028) and paragraph separator (\u2029) symbols now parse correctly instead of resulting in a SyntaxError.

Leave a Reply

Your email address will not be published. Required fields are marked *