ES6, ES7, ES8, ES9, and ES10 New features ES stands for ECMAScript. ECMAScript is a standardized scripting language developed by the ECMA. The current version of ECMAScript used by JavaScript is ECMA-417. The latest information about ECMA can be found in ECMA News.

New ES6 Features (2015)

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

  • class
  • modular
  • Arrow function
  • Function parameter default value
  • Template string
  • Deconstruction assignment
  • Extension operator
  • Short for object property
  • Promise
  • Let the Const

1. Class

Developers familiar with pure object-oriented languages such as Java, Object-C, C #, etc., will have a special feeling for class. ES6 introduces classes, which make Object-Oriented programming of JavaScript easier and easier to understand.

  class Animal {
    // Constructor, which will be called when instantiated. If not specified, there will be a default constructor with no arguments.
    constructor(name,color) {
      this.name = name;
      this.color = color;
    }
    // toString is an attribute on the prototype 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 constructor the super function, otherwise an error will be reported when creating a new instance.
    // If consructor is not set to the top, the default constructor with super will be added.
    super('cat'.'white');
    this.action = action;
  }
  toString() {
    console.log(super.toString()); }}var cat = new Cat('catch')
 cat.toString();

 // Instance cat is an instance of cat and Animal, 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 are mainly composed of export and import. Each module has its own separate scope. The mutual call relationship between modules is to specify the interface exposed by the module through export, and to reference the interface provided by other modules through import. It also creates namespaces for modules to prevent function naming conflicts.

Export (export)

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

Export variables

//test.js
export var name = 'Rainbow'
Copy the code

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

ES6 treats a file as a module that outputs a variable via 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 by import in another module.

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

Tip: 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 of ES6. => is not just a shorthand for the keyword function, it brings other benefits as well. The arrow function shares the same this with the code surrounding it, which should help you solve the this pointing problem. Experienced JavaScript developers are familiar with things like var self = this; Or var that = this refers to the pattern around this. But with =>, this pattern is not needed.

Structure of arrow function

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

// An 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

Tip: Both the arrow function and bind return a new function reference each time it is executed, so if you need the function reference to do something else (such as uninstall the listener), you must save the reference yourself.

Traps 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 also do:

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

Note that both the 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 uninstall the listener), you must save the reference yourself.

4. Default values of function parameters

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

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

Do not use default values:

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

This is generally fine, but when the argument has a Boolean value of false, it becomes a problem. For example, we call foo like this:

foo(0."")
Copy the code

Since 0 has a Boolean value of false, height will be 50. In the same way color is’ red ‘.

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

5. Template string

ES6 supports template strings, making string concatenation more concise and intuitive.

Without using template strings:

var name = 'Your name is ' + first + ' ' + last + '. '
Copy the code

Using template strings:

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

In ES6, concatenation of strings can be done with ${}, simply by enclosing variables in braces.

6. Deconstruct assignments

Destruct assignment syntax is a JavaScript expression that allows you to quickly extract values from arrays or objects and assign them to defined variables.

Gets the value in the array

Gets values from an array and assigns them to variables in the order of the 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
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 no value is retrieved 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); / / 7It is easy to swap the values of two variables by destructing assignments.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

Extension operators… You can expand array expressions or strings syntactically during function calls/array constructs; You can also expand an object expression key-value when constructing an object.

grammar

Function call:

myFunction(... iterableObj);Copy the code

Array constructs or strings:

[...iterableObj, '4'.'hello'.6];
Copy the code

When constructing objects, clone or copy properties (new feature in the ECMAScript 2018 specification) :

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

Application scenarios

Use the extension operator on function calls

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

Without the expansion syntax, you can only combine push, splice, and concat methods to make existing array elements part of a new array. With expansion syntax, constructing new arrays is easier 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 expansion of argument lists,… When constructing word groups, you can use them more than once in any position.

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 is the same as the object.assign () behavior, which executes shallow copies (traversing only one layer).

Join multiple arrays

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

Extension operators in ECMAScript 2018 add support for objects

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

React application

Usually when we encapsulate a component, we expose props for implementing the functionality. In most cases, external use should show the transfer props. But when passing a lot of props, it can be cumbersome, so we can use… The extension operator, which fetches all traversable properties of the parameter object, is passed.

Normally we would write it like this

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

The use of… Is the same as the above

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

Work with destructuring assignments to avoid passing in unnecessary arguments

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

8. Object property shorthand

ES6 allows you to set an object’s properties 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

The object must contain attributes 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 to write variables directly, very concise.

9.Promise

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

Do not use the ES6

Nested two setTimeout callback functions:

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 code above serializes asynchronous programming using two THEN’s to avoid callback hell:

10. Support let and const

Previously JS had no block-level scope. Const and let fill this convenient void. Const and let are both block-level scopes.

Variables defined using var are functionally scoped:

{
  var a = 10;
}

console.log(a); / / output 10
Copy the code

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

{
  let a = 10;
}

console.log(a); Or Error "ReferenceError: a is not defined"
Copy the code

New ES7 Features (2016)

ES2016 adds 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 and false otherwise.
  • The a ** b exponential 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 and returns true if it does, false otherwise.

The includes function is similar to the indexOf function, and the following two expressions are equivalent:

arr.includes(x)
arr.indexOf(x) >= 0
Copy the code

Let’s determine if the number contains an element:

What we did before ES7

Use indexOf() to verify the presence of an element in the array, using the return value -1:

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

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

Using ES7 includes()

Use includes() to verify the presence of an element in the array, which is more straightforward:

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

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

2. Index operators

The exponent operator ** was introduced in ES7, ** has the same properties as math.pow (..). Equivalent results.

No exponential operators are used

Use calculateExponent or math.pow () as a custom recursive function:

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 **, as with +, -, etc:

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

New ES8 Features (2017)

  • async/await
  • Object.values()
  • Object.entries()
  • String padding: padStart() and padEnd(), padding String up to current length
  • A comma is allowed at the end of a function argument list
  • Object.getOwnPropertyDescriptors()
  • ShareArrayBuffer and Atomics objects 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 and for… The of loop is used together to run asynchronous operations in a serial fashion. 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 Object’s own properties, excluding inherited values.

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

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

Values () :ES7 is not used

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

You can see from the code above that Object.values() saves us the step of iterating through keys and getting values based on those keys.

3.Object.entries()

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

Let’s iterate over the key and value of all attributes 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 needs to be filled. If the value is less than the length of the current string, the current string itself is returned.
  • PadString :(optional) padding string. If the string is too long and the length of the filled string exceeds the target length, only the leftmost part is reserved 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 needs to be filled. If the value is less than the length of the current string, the current string itself is returned.
  • PadString :(optional) padding string. If the string is too long, the length of the filled string exceeds the target length, only the leftmost part is reserved and the rest parts are 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 commas at the end of function argument lists

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

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 of the obj object’s own properties, 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

The SharedArrayBuffer object is used to represent a generic, fixed-length buffer of raw binary data, similar to an ArrayBuffer object, which can be used to create views on shared memory. Unlike ArrayBuffer, SharedArrayBuffer cannot be separated.

/ * * * *@param {*} Length Specifies the size, in bytes, of the array buffer created. *@returns {SharedArrayBuffer} A new SharedArrayBuffer object 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 to perform atomic operations on the SharedArrayBuffer object.

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

Multiple threads that share memory can simultaneously read and write data in the same location. Atomic operations ensure that the values of the data being read or written are as expected, that is, the next atomic operation will not be interrupted until the last atomic operation has finished.

  • Atomics.add()

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

  • Atomics.and()

Associates 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 of the element before it was updated.

  • Atomics.load()

Returns the value of the specified element in the array.

  • Atomics.or()

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

  • Atomics.store()

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

  • Atomics.sub()

Subtracts the array element at the specified location from the given value and returns the value of the element before the subtraction.

  • Atomics.xor()

Xor the array element at the specified position with the given value 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 processes wait until a particular condition is true, primarily for blocking purposes.

  • Atomics.wait()

Checks if the value at a specified location in the array is still the given value, and if so, suspends until woken up or timed out. The return value is “OK”, “not-equal”, or “time-out”. When called, an exception is thrown if the current thread does not allow blocking (most browsers do not allow wait() on the main thread).

  • Atomics.wake()

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

  • Atomics.isLockFree(size)

Can be used to check whether the current system supports hardware-level atomic operations. Returns true for arrays of specified size if the current system supports hardware-level atomic operations; Otherwise, it means that for the array, each atomic operation in the Atomics object can only be implemented using a lock. This function is intended for 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 mode
  • Regular expression Unicode escape
  • The template string for a non-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 will not work, nor 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 called before the internal asynchronous function is called.

ES2018 introduces asynchronous iterators, which are just like regular iterators, except that the next() method returns a Promise. So await can and for… The of loop is used together to run asynchronous operations in a serial fashion. Such as:

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

2.Promise.finally()

A chain of Promise calls either succeeds in reaching the last.then() or fails to trigger.catch(). In some cases, you’ll want to run the same code whether a Promise runs successfully or fails, such as clearing, deleting conversations, closing database connections, etc.

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

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

3. The Rest/Spread properties

ES2015 introduced Rest parameters and extended operators. Three points (…) Only for arrays. 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 an array into a separate parameter that can be passed to a function. For example, math.max () returns the maximum value in a given number:

const values = [99.100, -1.48.16];
console.log( Math.max(... values) );/ / 100
Copy the code

ES2018 provides the same Rest argument () and expansion operator for object deconstruction 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

Like arrays, Rest parameters can only be used at the end of a declaration. Furthermore, it only applies to the top layer of each object, not if there are nested objects in the object.

Extension operators can be used within other objects, for example:

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 the extension operator, such as obj2 = {… Obj1}, but this is just a shallow copy of the object. Also, if an attribute of object A is object B, then in the cloned object cloneB, that attribute points to object B.

4. Name capture groups using regular expressions

JavaScript regular expressions can return a matching object — an array of classes containing matching strings, such as: date parsing in YYYY-MM-DD format:

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

Such code is difficult to read, and changing the structure of a regular expression can change the index of a matching object.

ES2018 allows named capture groups to use symbols? , immediately after opening the capture parentheses, 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

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

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, capturing a currency symbol from a price:

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

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

ES2018 introduced works in the same way but matches the previous lookbehind so I can ignore the currency symbol 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 an affirmative reverse assertion, non-digit \D must exist. Also, there are negative reverse assertions, which indicate that a value must not exist, for example:

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

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

6. Regular expression dotAll mode

Regular expression midpoint. Matches any single character other than carriage return. The s tag changes this behavior by allowing line terminators, for example:

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

7. Regular expression Unicode escape

Until now, native access to Unicode character attributes in regular expressions was not allowed. ES2018 has added Unicode attribute escapes of the form \p{… } and \ {P… }, use the flag U (Unicode) setting in regular expressions, and in the \p block, you can set the attributes to be matched in key-value pairs rather than the content. Such as:

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

This feature improves readability and maintainability by eliminating the need for specific Unicode ranges for content type determination.

8. Template strings for non-escape sequences

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. Refer to template strings for more details.

New ES10 Features (2019)

  • The line delimiter (U + 2028) and segment delimiter (U + 2029) symbols are now allowed to match JSON in string literals
  • More friendly json.stringify
  • New Array flat() and flatMap() methods
  • New trimStart() and trimEnd() methods for String
  • Object.fromEntries()
  • Symbol.prototype.description
  • String.prototype.matchAll
  • Function. The prototype. The toString () now returns precise characters, including Spaces and comments
  • Simplify try {} catch {} and modify the catch binding
  • The new base data type BigInt
  • 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 in string literals

Previously, these symbols were treated as line terminators in string literals, so using them resulted in a SyntaxError exception.

2. More friendly json.stringify

If a character is entered in Unicode format but out of range, the original json.stringify returns a misformed Unicode string. A phase 3 proposal to change json.stringify is now implemented so that it outputs an escape sequence for it, making it valid Unicode (and represented as UTF-8)

3. Added Array flat() and flatMap() methods

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

The array.prototype.flat () flat() method iterates through the Array recursively at a specified depth and returns a new Array that combines all the elements with the elements in the traversed subarray.

  • Flat () is basically an array dimension reduction method
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]

// Use Infinity as the depth to expand a nested array of any depth
arr3.flat(Infinity); 
// [1, 2, 3, 4, 5, 6]
Copy the code
  • Second, you can use the property of the flat() 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 when combined 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]

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

4. Added the trimStart() and trimEnd() methods of String

The two new methods are easy to understand, removing whitespace at the beginning and end of the string, so we don’t have to declare them by example.

5.Object.fromEntries()

The object.entries () method returns an array of key-value pairs for a given Object’s own enumerable properties, arranged in the same order as for… The in loop returns the same order as it iterates through the object (the difference is that for-In loops also enumerate properties in the prototype chain).

Object.fromentries () is the reverse of Object.entries().

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

  • FromEntries converts 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
  • FromEntries converts Array to 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 symbols through the factory function Symbol (), you can choose to supply a string as a description with an argument:

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

Previously, the only way to access a description was to convert a 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 matched regular expressions and grouped capture results. Before matchAll appears, get all match information by calling regexp.exec in the loop (regexp requires /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 have to use the while loop with exec (and the regular expression uses the/g flag). Using matchAll returns an iterator with the return value for… Of, array spread, or array. From () can be more convenient to achieve functions:

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" ]MatchAll is better for groupingvar regexp = /t(e)(st(\d?) )/g;
var str = 'test1test2';

str.match(regexp); 
// Array ['test1', 'test2']
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. The Function. The prototype. The toString () now returns precise characters, including Spaces and comments

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

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

// ES2019 prints 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. Modify the catch binding

Prior to ES10, we had to bind exception variables to the catch clause syntactically, whether it was necessary or not. A lot of 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 base data type BigInt

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

Original link: juejin.cn/post/684490…