1. Object.fromEntries()

Converting data from one format to another is quite common in JavaScript. To facilitate the conversion of objects into arrays, ES2017 introduces the object.entrie () 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]. Such as:

const obj = {one: 1.two: 2.three: 3};

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

But what if we wanted to do the opposite and turn the key-value pair list into an object? Some programming languages, such as Python, provide dict() functions for this purpose. There are also _. FromPairs functions in Underscore. Js and Lodash. ES2019 brings similar functionality to JavaScript with the introduction of the object.fromentries () method, a static method that allows you to easily convert a list of key-value pairs into objects:

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

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

As you can see, object.fromentries () does the opposite of object.entries (). Although it was possible to achieve the same functionality as Object.fromentries (), it was a bit more complicated:

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}
Copy the code

Remember that the argument passed to Object.fromentries () can be any Object that implements an 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 pair in the Map:

const map = new Map(a); map.set('one'.1);
map.set('two'.2);

const obj = Object.fromEntries(map);

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

The object.fromentries () method is also useful for converting objects. Consider the following code:

const obj = {a: 4.b: 9.c: 16};

// Convert an object to an array
const arr = Object.entries(obj);

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

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

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

The code above converts the value in the object to its square root. To do this, it first converts the object to an array and then uses the map() method to take the square root of the values in the array, resulting in an array that can be converted back to the object. Another way to use Object.fromentries () is to process a query string for a URL, as shown in this example

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

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

In this code, the query string is passed to the URLSearchParams() constructor. The return value (that is, the URLSearchParams Object instance) is then passed to the Object.fromentries () method, which results in an Object containing each parameter as an attribute. The Object.fromentries () method is currently a phase 4 proposal, which means it is ready to be included in the ES2019 standard.

2. trimStart() and trimEnd()

The trimStart() and trimEnd() methods are implemented the same as trimLeft() and trimRight(). These methods are currently in phase 4 and will be added to the specification to be consistent with padStart() and padEnd(). Take a look at some examples:

const str = " string ";

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

// Same result
console.log(str.trimLeft());     // => "string "
console.log(str.trimRight());    // => " string"
Copy the code

For Web compatibility, trimLeft() and trimRight() will remain aliases for trimStart() and trimEnd().

3. flat() and flatMap()

The flat() method flattens multidimensional numbers into one-dimensional arrays

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

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

Previously, we often used reduce() or concat() to flatten multidimensional arrays:

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

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

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

Note that if the supplied array has empty values, they are discarded:

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

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

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

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]
Copy the code

The flatMap() method combines map() and flat() into one method. It first creates a new array using the return value of the provided function, and then concatenates all of the array’s subarray elements. Here’s an example:

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]
Copy the code

The depth level at which the array will be flattened is 1. To remove items from the result, simply return an empty array:

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]
Copy the code

In addition to the current element being processed, the callback function receives the index of the element and a reference to the array itself. The Flat () and flatMap() methods are currently in phase 4.

4. The description property of the Symbol object

When you create a Symbol, you can add a description to it for debugging purposes. Sometimes it’s useful to be able to access description directly in your code. ES2019 adds read-only description to the Symbol object, which returns a string containing the Symbol description.

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

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

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

5. Optional catch

Sometimes the catch in a try catch statement doesn’t work. Consider the following code:

try {
  // Use browser functionality that may not be implemented yet
} catch (unused) {
  // We already handled the error in the callback function
}
Copy the code

The catch callback information in this code is not useful. But this is done to avoid syntaxErrors. ES2019 can omit parentheses around catch:

try {
  // ...
} catch {
  // ....
}
Copy the code

6. The String ES2020. Prototype. MatchAll

The matchAll() method is a phase 4 proposal of ES2020 that returns iterator objects for all matches (including capture groups) against regular expressions. In keeping with the match() method, TC39 chose matchAll over other suggested names, such as Matches or Ruby’s Scan. Here’s a simple example:

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]
Copy the code

The capture group match character Dr In this regular expression, followed by a dot and a space. \w+ matches any word character one or more times. And the G flag instructs the engine to search for patterns throughout the string. Previously, the exec() method had to be used in the loop to achieve the same result, which was not very efficient:

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]
Copy the code

It is important to note that although the match() method can be used with the global flag G to access all matches, it does not provide a capture group or index location for matches. Compare the following code:

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]
Copy the code

conclusion

In this article, we take a closer look at several key features introduced in ES2019, including Object.fromentries (), trimStart(), trimEnd(), flat(), flatMap(), The description property of the symbol object and an optional catch. Although some browsers do not fully implement these features, you can use Babel and other JavaScript converters and still use them in your projects.