Introduction to the

ES9 is a version released by the ECMA Association in June 2018. It is also called ES9 because it is the ninth version of ECMAScript.

Today we’ll cover the new features of ES9.

ES9 introduces three major features and two minor ones, which we’ll cover next.

Asynchronous traversal

In ES6, the concept of synchronous Iteration was introduced. With the reference to the Async operator in ES8, a new feature of asynchronous iteration Async Iteration was introduced in ES9.

For details, see my previous article on ES9’s new feature: Asynchronous iteration Async Iteration

Rest/Spread operator and object construction

Rest and Spread operators are both… , but the use of the scene and purpose is different.

Rest is mainly used for object deconstruction, and currently only supports object deconstruction and uncertain parameter description.

Spread is primarily used in the construction of literal objects.

Here we introduce them respectively:

Rest

When used in object deconstruction, REST will copy all the other enumerable properties of the object except the property names you already specified manually.

const obj = {foo: 1.bar: 2.baz: 3};
const{foo, ... rest} = obj;// Same as:
    // const foo = 1;
    // const rest = {bar: 2, baz: 3};
Copy the code

When used in arguments, rest represents all the remaining arguments:

function func({param1, param2, ... rest}) { // rest operator
    console.log('All parameters: ', {param1, param2, ... rest});// spread operator
    return param1 + param2;
}
Copy the code

Note that in Obj literals, the REST operator can only be placed at the top of Obj and can only be used once and last.

const{... rest, foo} = obj;// SyntaxError
const{foo, ... rest1, ... rest2} = obj;// SyntaxError
Copy the code

Of course you can also nest rest operators:

const obj = {
    foo: {
        a: 1.b: 2.c: 3,},bar: 4.baz: 5};const {foo: {a, ... rest1}, ... rest2} = obj;// Same as:
// const a = 1;
// const rest1 = {b: 2, c: 3};
// const rest2 = {bar: 4, baz: 5};
Copy the code

Spread

Spread is used to expand objects. Any property that can be expanded must be an enumerable.

> const obj = {foo: 1.bar: 2}; > {... obj,baz: 3}
{ foo: 1.bar: 2.baz: 3 }
Copy the code

If the object has the same attribute key, then the following attribute value overrides the previous attribute value:

> const obj = {foo: 1.bar: 2.baz: 3}; > {... obj,foo: true}
{ foo: true.bar: 2.baz: 3 }
> {foo: true. obj} {foo: 1.bar: 2.baz: 3 }
Copy the code

Create and copy objects

You can easily copy objects using the object. assign and Spread operators.

Let’s look at the simplest object copy example:

constclone1 = {... obj};const clone2 = Object.assign({}, obj);
Copy the code

The downside of such a copy is that it can only copy its own enumerable properties.

And the prototypes of the copied objects are object. prototype, that is, no prototypes of the copied objects are inherited.

> Object.getPrototypeOf(clone1) === Object.prototype
true
> Object.getPrototypeOf(clone2) === Object.prototype
true
> Object.getPrototypeOf({}) === Object.prototype
true
Copy the code

If you want to copy the object’s prototype at the same time, you can do this:

const clone1 = {__proto__: Object.getPrototypeOf(obj), ... obj};const clone2 = Object.assign(
    Object.create(Object.getPrototypeOf(obj)), obj);
Copy the code

Either specify the object’s built-in __proto__ attribute, or create a new object from obj’s PRtoType.

Note that the object’s built-in __proto__ property is only supported in some browsers.

Object.assign and spread can only copy enumerable attributes. If it’s a set or get attribute, or if you want to copy attributes (writable, Enumerable), You will need to use before we talk about the Object. The getOwnPropertyDescriptors.

const clone1 = Object.defineProperties({},
    Object.getOwnPropertyDescriptors(obj));

const clone2 = Object.create(
    Object.getPrototypeOf(obj),
    Object.getOwnPropertyDescriptors(obj)); Note that all the copies we use are shallow copies. If there is an object inside the copied object, only a reference to the object is copiedconst original = { prop: {}};const clone = Object.assign({}, original);

console.log(original.prop === clone.prop); // true
original.prop.foo = 'abc';
console.log(clone.prop.foo); // abc
Copy the code

Difference between Spread and bject.assign()

When Assgin copies an object, it calls the set method of the corresponding property, whereas spread does not.

For example, we first define a set method for Object.prototype:

Object.defineProperty(Object.prototype, 'foo', {
    set(value) {
        console.log('SET', value); }});const obj = {foo: 123};
Copy the code

Then look at the difference between copies:

> Object.assign({}, obj)
SET 123
{}

> { ...obj }
{ foo: 123 }
Copy the code

You can see that assign fires the set method, but spread does not.

Also, if the object property is unwritable, assign will report an error, but spread will not.

Let’s define an unwritable object:

Object.defineProperty(Object.prototype, 'bar', {
    writable: false.value: 'abc'});Copy the code

Take a look at the assignment:

> const tmp = {};
> tmp.bar = 123;
TypeError: Cannot assign to read only property 'bar'

> Object.assign({}, obj)
TypeError: Cannot assign to read only property 'bar'

> { ...obj }
{ bar: 123 }
Copy the code

Regular expression

New regular expression features in ES9 can be found in my article: regular expression RegExp

promise.finally

Promise introduces a new finally method in addition to the then and catch methods.

As with finally in Java, promise.finally must be executed.

promise
.then(result= >{...}). The catch (error= >{...}). Finally,() = > {···});
Copy the code

As with Java, we can do some resource cleaning in Finally:

let connection;
db.open()
.then(conn= > {
    connection = conn;
    return connection.select({ name: 'Jane' });
})
.then(result= >{... }) · · ·. The catch (error= > {
    // handle errors
})
.finally(() = > {
    connection.close();
});
Copy the code

In the example above, we open a connection to a database and close it in finally after we finish using it.

Template text and labeled template text

Template text and tagged template text were introduced in ES6 and fixed in ES9.

Template literals are literals entered in back quotes that parse variables using ${···} and support carriage return for line feeds.

const firstName = 'Jane';
console.log(`Hello ${firstName}! How are you today? `);

// Output:
// Hello Jane!
// How are you
// today?
Copy the code

Labeled template text is preceded by a function call:

String.raw`\u{4B}`
'\u{4B}'
Copy the code

String.raw is called a tag function.

raw(template: TemplateStringsArray, ... substitutions: any[]): string;Copy the code

The above code could also be rewritten as:

String.raw`\u004B`
'\u004B'
Copy the code

\u{4B} and \u004B are both Unicode representations of the character K.

The raw above can actually be expressed like this:

function tagFunc(tmplObj, substs) {
    return {
        Cooked: tmplObj,
        Raw: tmplObj.raw,
    };
}
Copy the code

We can use it like this:

> tagFunc`\u{4B}`;
{ Cooked: [ 'K'].Raw: [ '\\u{4B}']}Copy the code

Author: Flydean program stuff

This paper links: www.flydean.com/ecmascript-…

Source: Flydean’s blog

Welcome to pay attention to my public number: “procedures those things” the most popular interpretation, the most profound dry goods, the most concise tutorial, many you do not know the small skills you find!