This article introduces the new features of ES2018(ES9) to see how to use them.

Async /await asynchronous iteration

ES8 brings us async/await so that we can execute asynchronous functions in synchronous writing, but in loops:

async function foo(array) {
  for (let i of array) {
    awaitdoSomething(i); }}Copy the code

The above code does not perform as expected, and the loop itself remains synchronous and completes before the internal asynchronous function is called.

ES2018 introduces asynchronous iterators that make await and for… The of loop is used together to run asynchronous operations in a serial fashion.

async function foo(array) {
  for await (let i ofarray) { doSomething(i); }}Copy the code

Promise.finally()

ES6 introduced promises, but its results were either success then or failure catch, making some of our logic, such as performing state changes and ending callbacks, have to be written on both sides.

With finally(), the logic can only be placed in one place, much like jQuery ajax’s complete.

return new Promise((reslove, reject) = > {
  // ...
}).then((res) = > {
  // reslove
}).catch((err) = > {
  // reject
}).finally(() = > {
  // complete
});
Copy the code

Finally () no arguments are passed in.

Rest/Spread properties

ES2015 introduced Rest parameters and extended operators. It was three points… Only for arrays.

Rest parameter syntax allows us to represent a residual parameter as an array.

function foo(a, b, ... rest) {
  // a = 1
  // b = 2
  // rest = [3, 4, 5]
}

foo(1.2.3.4.5);
Copy the code

The expansion operator converts an array to a separate argument that can be passed to a function.

const nums = [1.2.3.4.5];
Math.max(... nums));/ / 5
Copy the code

Now objects can use them too.

function foo({ a, b, ... rest }) {
  // a = 1
  // b = 2
  // rest = { c: 3, d: 4, e: 5 
}

foo({
  a: 1.b: 2.c: 3.d: 4.e: 5
}); 
Copy the code
const object = {
  a: 1.b: 2.c: 3.d: 4.e: 5
};

const{ a, ... rest } = object;// a = 1
// b = 2
// rest = { c: 3, d: 4, e: 5 }
Copy the code

Like arrays, Rest parameters can only be used at the end of a declaration.

Regular expression S (dotAll mode) flag

In re,. Can match any character except newline characters.

/hello.es9/.test('hello\nes9');  // false
Copy the code

ES2018 introduces the dotAll pattern, where. Matches newlines by using the tag S option.

/hello.es9/s.test('hello\nes9');  // true
Copy the code

Regular expression Unicode escape

Currently in re, characters can be matched by the name of a character set. For example, S stands for blank

/^\s+$/u.test(' ');  // true
Copy the code

Added Unicode attribute escape in ES2018 with the form \p{… } and \ {P… }, using the flag U (Unicode) option in regular expressions.

/^\p{White_Space}+$/u.test(' ')       / / true Spaces
/^\p{Script=Greek}+$/u.test('mu epsilon tau ά')   // true is a Greek letter
/^\p{Script=Latin}+$/u.test('and then to decide Gru helped e')  // true matches Latin letters
/^\p{Surrogate}+$/u.test('\u{D83D}')  // true matches a single substitution character
Copy the code

Lookbehind Indicates the reverse assertion

JavaScript currently supports lookahead in regular expressions. This means that a match occurs, but the assertion is not contained in the entire match field.

For example, match the number of “hours” in the string “10 hours” :

const reg = /\d+(? = hours)/u;
const matched = reg.exec('10 hours');
matched[0];  / / 42
Copy the code

Matches the string “10 minutes” followed by a number other than “hours” :

const reg = /\d+(? ! hours)/u;
const matched = reg.exec('10 minutes');
matched[0];  / / 42
Copy the code

The ES2018 introduction works in the same way but matches the previous lookbehind.

Matches the number after “hours” in the string “hours10” :

const reg = / (? <=hours)\d+/u;
const matched = reg.exec('hours10');
matched[0];  / / 10
Copy the code

Matches string “minutes10” with a number not preceded by “hours” :

const reg = / (? 
      ;
const matched = reg.exec('minutes10');
matched[0];  / / 10
Copy the code

Named Capture Groups Regular expression Named capture groups

Currently, regular expression brackets are grouped by index numbers:

const reg = /(\d{4})-(\d{2})-(\d{2})/u;
const matched = reg.exec('2018-12-31');
matched[0];  / / 2018-12-12
matched[1];  / / 2018
matched[2];  / / 12
matched[3];  / / 31
Copy the code

The code is less readable, and changing the structure of a regular expression can change the index of a matching object.

ES2018 allows named capture groups to use symbols?

, you can specify the name of the matching content in the braces to be placed in groups to improve the readability of the code.

const reg = / (? 
      
       \d{4})-(? 
       
        \d{2})-(? 
        
         \d{2})/u
        
       
      ;
const matched = reg.exec('2018-12-31');
matched.groups.year;   / / 2018
matched.groups.month;  / / 12
matched.groups.day;    / / 31
Copy the code

Named capture groups can also be used in the replace() method. For example, to convert a date to a “year month day” format:

const reg = / (? 
      
       \d{4})-(? 
       
        \d{2})-(? 
        
         \d{2})/u
        
       
      ;
'2018-12-31'.replace(reg, $
      
        year $
       
         month $
        
          day
        
       
      );  December 31, 2018
Copy the code

The template string for a non-escape sequence

ES2018 removes syntactic restrictions on ECMAScript escaping sequences in tagged template strings.

Previously, \u started a Unicode escape, \x started a hexadecimal escape, and \ followed by a number started an octal escape. This makes it impossible to create specific strings, such as the Windows file path C:\uuu\ XXX \111.

The resources

  • What ‘s New ES2018 in

collection

  • New features of ES2021(ES12
  • New features for ES2020(ES11)
  • Nine new features that ES2019(ES10) brings
  • ES2018 (ES9) new features
  • ES2017 (ES8) new features
  • ES2016 (ES7) new features