ES is ECMAScript, a standardized scripting language developed by ECMA. The current version of ECMAScript used by JavaScript is ECMA-417. For the latest information about ECMA, visit ECMA News.

The ECMA specification is finalized by TC39. TC39 is a group of parties, including browser vendors, that meet to push JavaScript proposals along a strict development path. There are several main stages from proposal to ECMA specification:

  • Stage 0: Strawman — Submission of initial ideas.
  • Stage 1: Proposal — A formal proposal document initiated by at least one TC39 member that includes API instances.
  • Stage 2: Draft — The initial version of the functional specification, which contains two experimental implementations of the functional specification.
  • Stage 3: Candidate — The proposal specification is reviewed and feedback is gathered from the vendor
  • Stage 4: Finished — The proposal is ready for ECMAScript, but it may take longer to get to the browser or Nodejs.

New ES6 Features (2015)

ES6 has a lot of features, and it was only standardized nearly six years after ES5 was released (2009-11 to 2015-6). There’s a lot of time between releases, so there are a lot of features in ES6. Here are a few common ones:

  • class
  • modular
  • Arrow function
  • Default values for function arguments
  • Template string
  • Deconstruction assignment
  • Extension operator
  • Shorthand for object property
  • Promise
  • Let the Const

1. Class

For developers familiar with Java, Object-C, C # and other pure object-oriented languages, class will have a special feeling. ES6 introduced classes to make object-oriented programming in JavaScript much simpler and easier to understand.

  class Animal {
    // The constructor that will be called when instantiated, if not specified, will have a default constructor with no arguments.
    constructor(name,color) {
      this.name = name;
      this.color = color;
    }
    // toString is a property on the stereotype object
    toString() {
      console.log('name:' + this.name + ',color:' + this.color); }}var animal = new Animal('dog'.'white');// Instantiate Animal
 animal.toString();

 console.log(animal.hasOwnProperty('name')); //true
 console.log(animal.hasOwnProperty('toString')); // false
 console.log(animal.__proto__.hasOwnProperty('toString')); // true

 class Cat extends Animal {
  constructor(action) {
    // Subclasses must specify the super function in constructor, otherwise an error will be reported when creating an instance.
    // Constructor with the default super function will be added if the top consructor is not set.
    super('cat'.'white');
    this.action = action;
  }
  toString() {
    console.log(super.toString()); }}var cat = new Cat('catch')
 cat.toString();

 // the instance cat is an instance of cat and Animal, which is identical to Es5.
 console.log(cat instanceof Cat); // true
 console.log(cat instanceof Animal); // true

Copy the code

2. Module

ES5 does not support native modularity, and modules are added as an important part of ES6. The functions of the module mainly consist of export and import. Each module has its own scope. The calling relationship between modules is to specify the interfaces exposed by the module through export, and to refer to the interfaces provided by other modules through import. Namespaces are also created for modules to prevent naming conflicts for functions.

Export (export)

ES6 allows you to export multiple variables or functions within a module using export.

Export variables

//test.js
export var name = 'Rainbow'

Copy the code

Note: ES6 not only supports the export of variables, but also supports the export of constants. export const sqrt = Math.sqrt; // Export the constant

ES6 treats a file as a module that exports a variable through export. A module can also output multiple variables simultaneously.

 //test.js
 var name = 'Rainbow';
 var age = '24';
 export {name, age};

Copy the code

The export function

// myModule.js
export function myModule(someArg) {
  return someArg;
}  

Copy the code

Import (import)

Once the output of a module is defined, it can be referenced in another module by import.

import {myModule} from 'myModule';// main.js
import {name,age} from 'test';// test.js

Copy the code

Note: An import statement can import both default functions and other variables. import defaultMethod, { otherMethod } from ‘xxx.js’;

3. Arrow function

This is one of the most exciting features in ES6. => It’s not just shorthand for the keyword function, but it has other benefits as well. The arrow function shares the same “this” with the code surrounding it, which helps you solve the “this” problem. Experienced JavaScript developers are familiar with things like var self = this; Or var that = this. But with =>, you don’t need this model.

The structure of the arrow function

The arrow => of an arrow function is preceded by an empty parenthesis, a single argument name, or multiple argument names enclosed in parentheses. The arrow can be followed by an expression (as the return value of the function), or by the body of the function enclosed in curly braces (the value must be returned by return itself; otherwise, undefined).

// Example of the arrow function() = >1
v=>v+1
(a,b)=>a+b
()=>{
    alert("foo");
}
e=>{
    if (e == 0) {return 0;
    }
    return 1000/e;
}

Copy the code

Note: Both the arrow function and bind return a new function reference each time they are executed, so if you need the function reference to do something else (such as unmount a listener), you must keep the reference yourself.

Trap when uninstalling listeners

Wrong way

class PauseMenu extends React.Component{
    componentWillMount(){
        AppStateIOS.addEventListener('change'.this.onAppPaused.bind(this));
    }
    componentWillUnmount(){
        AppStateIOS.removeEventListener('change'.this.onAppPaused.bind(this));
    }
    onAppPaused(event){
    }
}

Copy the code

The right thing to do

class PauseMenu extends React.Component{
    constructor(props){
        super(props);
        this._onAppPaused = this.onAppPaused.bind(this);
    }
    componentWillMount(){
        AppStateIOS.addEventListener('change'.this._onAppPaused);
    }
    componentWillUnmount(){
        AppStateIOS.removeEventListener('change'.this._onAppPaused);
    }
    onAppPaused(event){
    }
}

Copy the code

In addition to the above, we can do the following:

class PauseMenu extends React.Component{
    componentWillMount(){
        AppStateIOS.addEventListener('change'.this.onAppPaused);
    }
    componentWillUnmount(){
        AppStateIOS.removeEventListener('change'.this.onAppPaused);
    }
    onAppPaused = (event) = > {
        // Define the function directly as a property of the arrow function, which is initialized with the this pointer bound}}Copy the code

Note that both bind and arrow functions return a new function reference each time they are executed, so if you need the function reference to do something else (such as unmount listeners), you must save the reference yourself.

4.Default values for function arguments

ES6 supports setting default values for functions when they are defined:

function foo(height = 50, color = 'red')
{
    // ...
}

Copy the code

Default values are not used:

function foo(height, color)
{
    var height = height || 50;
    var color = color || 'red';
    / /...
}

Copy the code

This is usually fine, but it becomes problematic when the parameter’s Boolean value is false. For example, we call foo like this:

foo(0, "")

Copy the code

Since the Boolean value of 0 is false, the height will be 50. Similarly, the value of color is’ red ‘.

Therefore, function parameter defaults can not only make the code cleaner but also avoid some problems.

5. Template characters

ES6 supports template strings, which makes concatenation of strings more concise and intuitive.

Do not use template strings:

var name = 'Your name is ' + first + ' ' + last + '. '

Copy the code

Using a template string:

var name = `Your name is ${first} ${last}. `

Copy the code

String concatenation is done in ES6 with ${}, just by putting variables in curly braces.

6.Deconstruction assignment

Destruct assignment syntax is an expression in JavaScript that allows you to quickly extract values from an array or object and assign them to a defined variable.

Gets the value in the array

We get values from the array and assign them to variables in the order that corresponds to the order of objects in the array.

var foo = ["one"."two"."three"."four"];

var [one, two, three] = foo;
console.log(one); // "one"
console.log(two); // "two"
console.log(three); // "three"

// If you want to ignore some values, you can get the values you want as follows
var [first, , , last] = foo;
console.log(first); // "one"
console.log(last); // "four"

// You can also write like this
var a, b; // Declare variables first

[a, b] = [1.2];
console.log(a); / / 1
console.log(b); / / 2

Copy the code

If you don’t get a value from the array, you can set a default value for the variable.

var a, b;

[a=5, b=7] = [1];
console.log(a); / / 1
console.log(b); / / 7

Copy the code

Deconstructing assignments makes it easy to exchange the values of two variables.

var a = 1;
var b = 3;

[a, b] = [b, a];
console.log(a); / / 3
console.log(b); / / 1


Copy the code

Gets the value in the object

const student = {
  name:'Ming'.age:'18'.city:'Shanghai'  
};

const {name,age,city} = student;
console.log(name); // "Ming"
console.log(age); 18 "/ /"
console.log(city); // "Shanghai"

Copy the code

7. Spread operator

The extension operator… Array expressions or strings can be expanded syntactically during function calls/array construction; You can also expand an object expression as a key-value when an object is constructed.

grammar

Function call:

myFunction(... iterableObj);Copy the code

An array construct or string:

[...iterableObj, '4'.'hello'.6];

Copy the code

Cloning or copying properties when constructing objects (new to the ECMAScript 2018 specification) :

letobjClone = { ... obj };Copy the code

Application scenarios

Use the extension operator when a function is called

function sum(x, y, z) {
  return x + y + z;
}
const numbers = [1.2.3];

// Do not use the extension operator
console.log(sum.apply(null, numbers));

// Use the extension operator
console.log(sum(... numbers));/ / 6

Copy the code

Constructing an array

Push, splice, concat, and other methods can be used to make the elements of an existing array part of a new array without expansion syntax. With the expansion syntax, constructing new arrays becomes simpler and more elegant:

const stuendts = ['Jine'.'Tom']; 
const persons = ['Tony'. stuendts,'Aaron'.'Anna'];
conslog.log(persions)// ["Tony", "Jine", "Tom", "Aaron", "Anna"]

Copy the code

Similar to the argument list expansion,… It can be used multiple times in any location when constructing a word group.

Copy an array

var arr = [1.2.3];
var arr2 = [...arr]; // equivalent to arr.slice()
arr2.push(4); 
console.log(arr2)/ / [1, 2, 3, 4]

Copy the code

The expansion syntax behaves the same as object.assign (), executing a shallow copy (traversing only one level).

Concatenating arrays

var arr1 = [0.1.2];
var arr2 = [3.4.5];
var arr3 = [...arr1, ...arr2];// Append all elements of arR2 to arR1 and return
/ / is equivalent to
var arr4 = arr1.concat(arr2);

Copy the code

Extended operators have added support for objects in ECMAScript 2018

var obj1 = { foo: 'bar'.x: 42 };
var obj2 = { foo: 'baz'.y: 13 };

varclonedObj = { ... obj1 };// Clone object: {foo: "bar", x: 42}

varmergedObj = { ... obj1, ... obj2 };{foo: "baz", x: 42, y: 13}

Copy the code

Application in React

Usually when we encapsulate a component, we expose props to implement the functionality. Pass props that should be displayed externally in most cases. But when passing a large number of props can be tedious, we can use… (the extension operator, which retrives all the traversable properties of the parameter object).

Normally we would write it like this

<CustomComponent name ='Jine' age ={21} / >Copy the code

The use of… That’s the same thing as the above

const params = {
	name: 'Jine'.age: 21} <CustomComponent {... params} />Copy the code

Cooperate with destruct assignment to avoid passing unnecessary parameters

var params = {
	name: '123'.title: '456'.type: 'aaa'
}

var{ type, ... other } = params; <CustomComponent type='normal' number={2} {... <CustomComponent type='normal' number={2} name='123' title='456' />Copy the code

8. Shorthand for object properties

ES6 allows you to set a property of an object without specifying the property name.

Do not use the ES6

const name='Ming',age='18',city='Shanghai';
   
const student = {
    name:name,
    age:age,
    city:city
};
console.log(student);//{name: "Ming", age: "18", city: "Shanghai"}

Copy the code

Objects must contain properties and values, which is very redundant.

Use the ES6

const name='Ming',age='18',city='Shanghai';
  
const student = {
    name,
    age,
    city
};
console.log(student);//{name: "Ming", age: "18", city: "Shanghai"}

Copy the code

Object, which is very concise.

9.Promise

Promise is a more elegant solution to asynchronous programming than the traditional callback solution. It was first proposed and implemented by the community, and ES6 wrote it into the language standard, unifying usage and providing Promise objects natively.

Do not use the ES6

Nest two setTimeout callbacks:

setTimeout(function()
{
    console.log('Hello'); // Output "Hello" after 1 second
    setTimeout(function()
    {
        console.log('Hi'); // Output "Hi" after 2 seconds
    }, 1000);
}, 1000);

Copy the code

Use the ES6

var waitSecond = new Promise(function(resolve, reject)
{
    setTimeout(resolve, 1000);
});

waitSecond
    .then(function()
    {
      console.log("Hello"); // Output "Hello" after 1 second
      return waitSecond;
    })
    .then(function()
    {
        console.log("Hi"); // Output "Hi" after 2 seconds
    });

Copy the code

The above code uses two THEN’s for asynchronous programming serialization, avoiding callback hell:

10. Support let and const

Previously, JS did not have a block-level scope. Const and let fill this convenient gap. Const and let are block-level scopes.

Variables defined using var are at function level scope:

{
  var a = 10;
}

console.log(a); / / output 10

Copy the code

Variables defined with let and const are block-level scoped:

{
  let a = 10;
}

console.log(a); //-1 or Error "ReferenceError: a is not defined"
Copy the code

New ES7 Features (2016)

ES2016 added two small features to illustrate the standardization process:

  • The array includes() method, which determines whether an array contains a specified value, returning true if it does, false otherwise.
  • The a ** b exponent operator, which is the same as Math.pow(a, b).

1.Array.prototype.includes()

The includes() function determines whether an array contains a specified value, returning true if it does, and false otherwise.

The includes function is similar to indexOf. The following two expressions are equivalent:

arr.includes(x)
arr.indexOf(x) >= 0

Copy the code

Next, we determine whether the number contains an element:

What we did before ES7

Use indexOf() to verify the presence of an element in the array, depending on whether the return value is -1:

let arr = ['react'.'angular'.'vue'];

if (arr.indexOf('react')! = =- 1)
{
    console.log('the react there');
}

Copy the code

Use ES7 includes()

Use includes() to verify the presence of an element in the array for a more intuitive purpose:

let arr = ['react'.'angular'.'vue'];

if (arr.includes('react'))
{
    console.log('the react there');
}
Copy the code

2. Exponential operator

In ES7, the exponent operator ** was introduced, ** has the same function as math.pow (..) Equivalent calculation result.

Do not use the exponential operator

Use the custom recursive function calculateExponent or math.pow () to calculate the exponent:

function calculateExponent(base, exponent)
{
    if (exponent === 1)
    {
        return base;
    }
    else
    {
        return base * calculateExponent(base, exponent - 1); }}console.log(calculateExponent(2.10)); / / output 1024
console.log(Math.pow(2.10)); / / output 1024
Copy the code

Use the exponential operator

Use the exponent operator **, just like the +, -, and so on:

console.log(2六四事件10);/ / output 1024
Copy the code

New ES8 Features (2017)

  • async/await
  • Object.values()
  • Object.entries()
  • String padding: padStart()andpadEnd()To fill the string to the current length
  • A comma is allowed at the end of the function argument list
  • Object.getOwnPropertyDescriptors()
  • ShareArrayBufferandAtomicsObject for reading and writing from shared memory locations

1.async/await

ES2018 introduces asynchronous iterators, which are just like regular iterators except that the next() method returns a Promise. So await can be combined with for… Of loop to run asynchronous operations in a serial manner. Such as:

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

2.Object.values()

Object.values() is a new function similar to object.keys (), but returns all the values of the property of the Object itself, excluding inherited values.

Suppose we want to traverse all the values of the following object obj:

const obj = {a: 1.b: 2.c: 3};
Copy the code

Do not use object.values () :ES7

const vals=Object.keys(obj).map(key= >obj[key]);
console.log(vals);/ / [1, 2, 3]
Copy the code

Use the Object. The values () : ES8

const values=Object.values(obj1);
console.log(values);/ / [1, 2, 3]
Copy the code

As you can see from the code above, object.values () saves us the step of going through keys and getting values from them.

3.Object.entries()

The object.entries () function returns an array of key-value pairs for the enumerable properties of a given Object itself.

Next, let’s iterate over the keys and values of all properties of the obj object:

Do not use object.entries () :ES7

Object.keys(obj).forEach(key= >{
	console.log('key:'+key+' value:'+obj[key]);
})
//key:a value:1
//key:b value:2
//key:c value:3
Copy the code

The use of the Object. Entries () : ES8

for(let [key,value] of Object.entries(obj1)){
	console.log(`key: ${key} value:${value}`)}//key:a value:1
//key:b value:2
//key:c value:3

Copy the code

4.String padding

In ES8 two instances have been added to the String String. The function prototype. PadStart and String prototype. PadEnd, allows you to an empty String or other String is added to the beginning or end of the original String.

String.padStart(targetLength,[padString])

  • TargetLength: the targetLength to which the current string is to be filled. If this value is less than the length of the current string, the current string itself is returned.
  • PadString :(optional) padding a string. If the string is so long that the length of the filled string exceeds the target length, only the leftmost part is retained and the rest is truncated. The default value of this parameter is “”.
console.log('0.0'.padStart(4.'10')) / / 10.0
console.log('0.0'.padStart(20))/ / 0.00
Copy the code

String.padEnd(targetLength,padString])

  • TargetLength: the targetLength to which the current string is to be filled. If this value is less than the length of the current string, the current string itself is returned.
  • PadString :(optional) padding a string. If the string is so long that the length of the filled string exceeds the target length, only the leftmost part is retained and the rest is truncated. The default value of this parameter is “”.
console.log('0.0'.padEnd(4.'0')) / / 0.00
console.log('0.0'.padEnd(10.'0'))/ / 0.00000000
Copy the code

5. Allow a comma at the end of the function argument list

The main effect is to make it easier to modify the same function when using Git for collaborative development and reduce unnecessary row changes.

6.Object.getOwnPropertyDescriptors()

Object. GetOwnPropertyDescriptors () function is used to retrieve an Object of all their property descriptors, if you don’t have any own properties, it returns null objects.

Function prototype:

Object.getOwnPropertyDescriptors(obj)
Copy the code

Returns a descriptor for all self properties of an obj object, or an empty object if there are none.

const obj2 = {
	name: 'Jine',
	get age() { return '18'}};Object.getOwnPropertyDescriptors(obj2)
/ / {
// age: {
// configurable: true,
// enumerable: true,
// get: function age(){}, //the getter function
// set: undefined
/ /},
// name: {
// configurable: true,
// enumerable: true,
// value:"Jine",
// writable:true
/ /}
// }
Copy the code

7. SharedArrayBuffer object

SharedArrayBuffer objects are used to represent a generic, fixed-length buffer of raw binary data, similar to ArrayBuffer objects, and both can be used to create views in shared memory. Unlike ArrayBuffer, SharedArrayBuffer cannot be detached.

/** ** @param {*} length Size of the array buffer to be created, in bytes. * @returns {SharedArrayBuffer} A new SharedArrayBuffer of a specified size. Its contents are initialized to 0. * /
new SharedArrayBuffer(length)
Copy the code

8. Atomics object

The Atomics object provides a set of static methods for atomizing SharedArrayBuffer objects.

These atomic operations belong to the Atomics module. Unlike a normal global object, Atomics is not a constructor and therefore cannot be called using the new operator or directly as a function. All of Atomics’ properties and methods are static (just like the Math object).

Multiple threads of shared memory can simultaneously read and write data in the same location. An atomic operation ensures that the value of the data being read or written is as expected, that the next atomic operation will not start until the last one has finished, and that its operation will not be interrupted.

  • Atomics.add()

Adds the array elements at the specified position to the given value and returns the value of the element before the addition.

  • Atomics.and()

Aligns the array element at the specified position with the given value and returns the value of the element before the operation.

  • Atomics.compareExchange()

If the specified element in the array is equal to the given value, it is updated to the new value and the original value of the element is returned.

  • Atomics.exchange()

Updates the specified element in the array to the given value, and returns the value before the element was updated.

  • Atomics.load()

Returns the value of the specified element in the array.

  • Atomics.or()

Aligns an array element at the specified position with the given value, and returns the value of the element before the or operation.

  • Atomics.store()

Sets the specified element in the array to the given value and returns that value.

  • Atomics.sub()

Subtracts an array element at the specified position from the given value and returns the value of that element before subtraction.

  • Atomics.xor()

Differentiates or from the given value an array element at the specified position, and returns the value of the element before the xOR operation.

The wait() and wake() methods use the Linux Futexes model (fast user-space mutex) to make a process wait until a particular condition is true, and are mainly used for blocking.

  • Atomics.wait()

Detects whether the value at a specified position in the array is still the given value, and if so, remains suspended until awakened or timed out. The return value is “OK”, “not-equal”, or “time-out”. When called, an exception is thrown if the current thread is not allowed to block (most browsers do not allow wait() to be called on the main thread).

  • Atomics.wake()

Wakes up the threads in the wait queue that are waiting on the element at the specified location in the array. The return value is the number of threads that were successfully awakened.

  • Atomics.isLockFree(size)

Can be used to detect whether the current system supports hardware-level atomic operations. Return true for an array of specified size if the current system supports hardware-level atomic operations. Otherwise, this means that for the array, each atomic operation in the Atomics object can only be implemented with a lock. This function is aimed at technical experts. –>

New ES9 Features (2018)

  • Asynchronous iterative
  • Promise.finally()
  • Rest/Spread properties
  • Regular Expression Named Capture Groups
  • Regular expression reverse assertion (lookbehind)
  • Regular expression dotAll pattern
  • Regular expression Unicode escapes
  • A template string that is not an escape sequence

1. Asynchronous iteration

At some point in async/await, you may try to call an asynchronous function in a synchronous loop. Such as:

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

This code won’t work, and neither will the following:

async function process(array) {
  array.forEach(async i => {
    await doSomething(i);
  });
}
Copy the code

In this code, the loop itself remains synchronized and is fully called before the internal asynchronous function.

ES2018 introduces asynchronous iterators, which are just like regular iterators except that the next() method returns a Promise. So await can be combined with for… Of loop to run asynchronous operations in a serial manner. Such as:

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

2.Promise.finally()

A Promise call chain either successfully reaches the last.then(), or fails to trigger.catch(). In some cases, you want to run the same code, such as clear, delete conversations, close database connections, and so on, whether the Promise runs successfully or fails.

.finally() allows you to specify the final logic:

function doSomething() {
  doSomething1()
  .then(doSomething2)
  .then(doSomething3)
  .catch(err= > {
    console.log(err);
  })
  .finally((a)= > {
    // finish here!
  });
}
Copy the code

3. The Rest/Spread properties

ES2015 introduces Rest parameters and extension operators. Three points (…) Arrays only. Rest parameter syntax allows us to represent an indefinite number of parameters as an array.

restParam(1.2.3.4.5);

function restParam(p1, p2, ... p3) {
  // p1 = 1
  // p2 = 2
  // p3 = [3, 4, 5]
}
Copy the code

The expansion operator works in reverse, converting the array into individual arguments that can be passed to the function. For example, math.max () returns the maximum value of a given number:

const values = [99, 100, -1, 48, 16]; console.log( Math.max(... values) ); / / 100Copy the code

ES2018 provides the same Rest parameters () and expansion operators for object destructuring as arrays. A simple example:

const myObject = {
  a: 1.b: 2.c: 3
};

const{ a, ... x } = myObject;// a = 1
// x = { b: 2, c: 3 }
Copy the code

Or you can use it to pass arguments to functions:

restParam({
  a: 1.b: 2.c: 3
});

function restParam({ a, ... x }) {
  // a = 1
  // x = { b: 2, c: 3 }
}
Copy the code

As with arrays, Rest parameters can only be used at the end of the declaration. In addition, it only applies at the top level of each object, not if there are nested objects in the object.

Extension operators can be used within other objects, such as:

const obj1 = { a: 1.b: 2.c: 3 };
constobj2 = { ... obj1,z: 26 };
// obj2 is { a: 1, b: 2, c: 3, z: 26 }
Copy the code

You can copy an object using an extension operator like obj2 = {… Obj1}, but this is only a shallow copy of the object. In addition, if an object A has an attribute of object B, then in the cloned object cloneB, that attribute points to object B.

4. The regular expression is used to name the capture group

JavaScript regular expressions can return a matching object — a class-like array of matching strings, for example: parse a date in the format YYYY-MM-DD:

const
  reDate = / [0-9] {4}) - ([0-9] {2}) - ([0-9] {2}) /,
  match  = reDate.exec('2018-04-30'),
  year   = match[1]./ / 2018
  month  = match[2].// 04
  day    = match[3]; / / 30
Copy the code

This code is hard to read, and changing the structure of the regular expression can change the index of the matched object.

Does ES2018 allow named capture groups to use symbols?

, after opening the capture parenthesis (immediately after naming, as shown in the following example:

const
  reDate = / (? 
      
       [0-9]{4})-(? 
       
        [0-9]{2})-(? 
        
         [0-9]{2})/
        ,
  match  = reDate.exec('2018-04-30'),
  year   = match.groups.year,  / / 2018
  month  = match.groups.month, // 04
  day    = match.groups.day;   / / 30
Copy the code

Any named group that fails to match will return undefined.

Named capture can also be used in the replace() method. For example, to convert a date to the U.S. format MM-DD-YYYY:

const
  reDate = / (? 
      
       [0-9]{4})-(? 
       
        [0-9]{2})-(? 
        
         [0-9]{2})/
        ,
  d      = '2018-04-30',
  usDate = d.replace(reDate, '$<month>-$<day>-$<year>');
Copy the code

5. Regular expression reverse assertion

JavaScript currently supports lookahead in regular expressions. This means that a match occurs, but there is no capture, and the assertion is not included in the entire match field. For example, to capture a currency symbol from a price:

const
  reLookahead = /\D(? =\d+)/,
  match       = reLookahead.exec('$123.89');

console.log( match[0]);/ / $
Copy the code

ES2018 introduces a reverse assertion that works the same way but matches the previous lookbehind, so I can ignore the currency sign and simply capture the number of prices:

const
  reLookbehind = / (? <=\D)\d+/,
  match        = reLookbehind.exec('$123.89');

console.log( match[0]);/ / 123.89
Copy the code

The above is the affirmative reverse assertion that the non-number \D must exist. Similarly, there are negative reverse assertions, which indicate that a value must not exist, such as:

const
  reLookbehindNeg = / (? 
      ,
  match           = reLookbehind.exec('$123.89');

console.log( match[0]);// null
Copy the code

6. Regular expression dotAll mode

Midpoint of a regular expression. Matches any single character except carriage return. The s flag changes this behavior to allow line terminators, such as:

/hello.world/.test('hello\nworld');  // false
/hello.world/s.test('hello\nworld'); // true
Copy the code

7. Regular expression Unicode escapes

Until now, local access to Unicode character properties in regular expressions has not been allowed. ES2018 added Unicode attribute escapes — form \p{… } and \ {P… }, using the u (Unicode) tag in the regular expression, and within the \p block, you can set the attribute to match as a key-value pair rather than the actual content. Such as:

const reGreekSymbol = /\p{Script=Greek}/u;
reGreekSymbol.test('PI.); // true
Copy the code

This feature improves readability and maintainability by avoiding the use of specific Unicode ranges for content type determination.

8. Template strings that are not escape sequences

Before, \u starts a Unicode escape, \x starts a hexadecimal escape, \ followed by a number starts an octal escape. This makes it impossible to create specific strings, such as Windows file path C:\uuu\ XXX \111. Refer to the template string for more details.

New ES10 Features (2019)

  • Line delimiter (U + 2028) and segment delimiter (U + 2029) symbols are now allowed to match JSON within string literals
  • More friendly json.stringify
  • Added Arrayflat()Methods andflatMap()methods
  • Added StringtrimStart()Methods andtrimEnd()methods
  • Object.fromEntries()
  • Symbol.prototype.description
  • String.prototype.matchAll
  • Function.prototype.toString()Now return exact characters, including Spaces and comments
  • To simplify thetry {} catch {}, modifycatchThe binding
  • New basic data typesBigInt
  • globalThis
  • import()
  • Legacy RegEx
  • Private instance methods and accessors

1. Line delimiter (U + 2028) and segment delimiter (U + 2029) symbols are now allowed to match JSON within string literals

Previously, these symbols were treated as line terminators in string literals, so their use would result in a SyntaxError exception.

2. More friendly json. stringify

If you enter a character in Unicode format but out of range, the original json. stringify returns an ill-formed Unicode string. A Phase 3 proposal that changes json.stringify is now implemented, so it outputs an escape sequence for it, making it valid Unicode (and represented as UTF-8)

3. Array is addedflat()Methods andflatMap()methods

Flat () and flatMap() are essentially reduce and concat operations.

Array.prototype.flat()

The flat() method recurses through the array at a specified depth and returns a new array combining all the elements with the elements in the subarray it traverses.

  • flat()Method is basically used to reduce the dimension of an array
var arr1 = [1.2[3.4]];
arr1.flat(); 
// [1, 2, 3, 4]

var arr2 = [1.2[3.4[5.6]]];
arr2.flat();
// [1, 2, 3, 4, [5, 6]]

var arr3 = [1.2[3.4[5.6]]];
arr3.flat(2);
// [1, 2, 3, 4, 5, 6]

// Expand the nested array of any depth, using Infinity as the depth
arr3.flat(Infinity); 
// [1, 2, 3, 4, 5, 6]
Copy the code
  • Secondly, it can be usedflat()Method to remove empty items from an array
var arr4 = [1.2.4.5];
arr4.flat();
// [1, 2, 4, 5]
Copy the code

Array.prototype.flatMap()

The flatMap() method first maps each element using a mapping function, and then compresses the result into a new array. It is almost identical to a map and a flat with a depth value of 1, but flatmaps are usually slightly more efficient at merging into one method. Here we compare the map method with the flatMap method.

var arr1 = [1.2.3.4];

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

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

// Only flatters the array returned by the function in flatMap
arr1.flatMap(x= > [[x * 2]]);
// [[2], [4], [6], [8]
Copy the code

4. Added StringtrimStart()Methods andtrimEnd()methods

These two new methods are easy to understand, removing whitespace characters at the beginning and end of the string, respectively, so I don’t need to use an example here.

5.Object.fromEntries()

The object.entries () method returns an array of key-value pairs for enumerable properties of a given Object, arranged in parallel with the for… The in loop returns the same order as it traverses the object (the difference is that the for-in loop also enumerates properties in the prototype chain).

whileObject.fromEntries()It isObject.entries()The reverse.

The object.fromentries () function passes in a list of key-value pairs and returns a new Object with them. The iteration argument should be an object that implements the @iterator method, returning an iterator object. It generates an array-like object with two elements, the first being the value to be used as the property key, and the second being the value associated with the property key.

  • Using object.fromentries, you can convert a Map to an Object:
const map = new Map([['foo'.'bar'], ['baz'.42]]);const obj = Object.fromEntries(map);
console.log(obj); // { foo: "bar", baz: 42 }
Copy the code
  • Using object. fromEntries, you can convert an Array to an Object:
const arr = [ ['0'.'a'], ['1'.'b'], ['2'.'c']].const obj = Object.fromEntries(arr);
console.log(obj); // { 0: "a", 1: "b", 2: "c" }
Copy the code

6.Symbol.prototype.description

When creating a Symbol using the factory function Symbol (), you can choose to provide a string as a description as an argument:

const sym = Symbol('The description');
Copy the code

Previously, the only way to access the description was to convert the symbol to a string:

assert.equal(String(sym), 'Symbol(The description)');
Copy the code

Now the introduction of the getter Symbol. The prototype. The description with direct access to the description:

assert.equal(sym.description, 'The description');
Copy the code

7.String.prototype.matchAll

The matchAll() method returns an iterator containing all the results of the matched regular expression and the group capture. Before matchAll appears, all matches are obtained by calling regexp.exec in the loop (regexp uses the /g flag:

const regexp = RegExp('foo*'.'g');
const str = 'table football, foosball';

while((matches = regexp.exec(str)) ! = =null) {
  console.log(`Found ${matches[0]}. Next starts at ${regexp.lastIndex}. `);
  // expected output: "Found foo. Next starts at 9."
  // expected output: "Found foo. Next starts at 19."
}
Copy the code

If you use matchAll, you don’t need to use the while loop and exec mode (and regular expressions need to use the/g flag). Using matchAll returns an iterator, paired with for… Of, array spread, or array. From () can be more convenient to implement:

const regexp = RegExp('foo*'.'g'); 
const str = 'table football, foosball';
let matches = str.matchAll(regexp);

for (const match of matches) {
  console.log(match);
}
// Array [ "foo" ]
// Array [ "foo" ]

// matches iterator is exhausted after the for.. of iteration
// Call matchAll again to create a new iterator
matches = str.matchAll(regexp);

Array.from(matches, m => m[0]);
// Array [ "foo", "foo" ]
Copy the code

MatchAll is better for grouping

var regexp = /t(e)(st(\d?) )/g;
var str = 'test1test2';

str.match(regexp); 
// Array ['test1', 'test2']
Copy the code
let array = [...str.matchAll(regexp)];

array[0];
// ['test1', 'e', 'st1', '1', index: 0, input: 'test1test2', length: 4]
array[1];
// ['test2', 'e', 'st2', '2', index: 5, input: 'test1test2', length: 4]
Copy the code

8.Function.prototype.toString()Now return exact characters, including Spaces and comments

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

// The comments section will not be printed before
console.log(foo.toString()); // function foo(){}

// ES2019 will print the comments together
console.log(foo.toString()); // function /* comment */ foo /* another comment */ (){}

// Arrow function
const bar /* comment */ = /* another comment */() = > {};console.log(bar.toString()); / / () = > {}
Copy the code

9. ModifycatchThe binding

Prior to ES10, we had to bind an exception variable to a catch clause via syntax, whether it was necessary or not. Many times catch blocks are redundant. The ES10 proposal allows us to simply omit variables.

Not a big change.

Before is

try {} catch(e) {}
Copy the code

Now it is

try {} catch {}
Copy the code

10. New basic data typesBigInt

There are now more than five basic data types (value types) (six after ES6). There are seven basic data types: String, Number, Boolean, Null, Undefined, Symbol, BigInt

ES6, ES7, and ES8 Study Guide