New features of ECMAScript

New features of ECMAScript

1. Introduction to ECMASCript

1,

Javascript
Language itself refers to
ECMASCript
, Just run on a different platform
Javascript
Expanded.
2,
Javascript
in
Web
The following uses include:
ECMASCript
+
Web APIs
(
BOM
,
DOM
).
3.
Javascript
in
Node.js
The following uses include:
ECMASCript
+
Node APIs
(
fs
,
net
,
etc.
).
4. Since 2016, ES has maintained one version iteration per year, what we said in the industry
ES6
Can refer to
ECMASCript
All standards.
5.
ES6
Great improvements have been made to the original foundation, which are mainly reflected in four aspects:

  • Enhancements to the original syntax, such as:
    Object.values()
    ,
    Object.assign()
    ...
  • Solve some problems or defects in the original syntax, such as:
    let
    ,
    const
    ,
    Block scope
    ...
  • New objects, new methods, new functions, such as:
    Proxy
    ,
    Reflect
    ,
    class
    Key words,
    extends
    Class inheritance...
  • Brand new data types and data structures, such as:
    Symbol
    ,
    Set
    ,
    Map
    ...

2. array deconstruction, object deconstruction

1. In the past, the way to obtain array elements was through array subscripts.

ES6
Obtaining array elements can be assigned according to the same position, or default values can be added. In addition, the collection can be obtained through the remaining operator.

const arr = [ 100 , 200 , 300 ] const [foo, bar, baz, car = 400 ] = arr const [bas, ...rest] = arr log (foo, bar, baz, CAR) //100 300 400 200 is log (BAS, REST) //100 [200 is, 300] copy the code

2. In the past, the way to obtain object properties was through the. Operator,

ES6
The attribute value can be obtained by the variable name being the same as the attribute name, or the attribute name can be renamed to add a default value to the attribute value.

const obj = { name : 'Tom' , age : 20 } const name = 'Jack' const { name : objName = 'default' } = obj log(objName) //Tom copy the code

3. template string and extension method

1. The general usage of template string supports variables, backquote escape, line break, interpolation operation

const name = 'peek' log( `hello es2015 name IS My $ {name + . 1 }/`/String/` ` ) copying the code

2. The tagged template string can process the string

const name = 'peek' const gender = true function myTagFunc ( string, name, gender ) { return string[ 0 ] + name + string[ 1 ] + gender + string[ 2 ] } const Result = myTagFunc `Hey, $ {name} IS A $ Gender} { ` Console .log (Result) //Hey, IS A PEEK to true copy the code

3.

ES6
The extension method of the provided string

const message = 'Error: foo is not defined' log(message.includes( 'foo' )) //true log(message.startsWith( 'Error' )) //true log(message.endsWith( 'defined' )) //true copy the code

4. ... operator

1. The function parameter transfer value adopts the remaining operator, which is best placed at the end of the formal parameter

const hello = ( sum, ...rest ) => { log(sum) //100 log(rest) //[1, 2, 3] } Hello ( 100 , . 1 , 2 , . 3 ) copying the code

2. Use spread operator in array

const ARR = [ '. 1' , '2' , '. 3' ] Console .log (ARR ...) //2. 3. 1 duplicated code

5. Object literal enhancement

const x = '11' const family = { x, y () { //Recommended writing, concise console .log( this ) //this points to family }, z : () => { //Recommended writing, easy to understand log( this .y) //this points to window log(family.y) //call the property of the family object return null }, //Calculate the attribute name as the attribute name [ Math .random()]: '33' } console .log(family) Copy code

6. Object object new method

log( Object .assign({ a : 1 , b : 2 }, { a : 3 , c : 4 })) //Object merge log( Object .assign({), { a : 3 , c : 4 }) ) //Shallow copy log(- 0 === + 0 ) //true log( null === null ) //true log( Object .is(- 0 , + 0 ))//false determining whether the object is equal to log ( Object .is ( null , null )) //to true copy the code

7. Proxy object (commonly known as: doorman)

1,

Proxy
The object hijacks the entire object in a non-invasive way and supervises the entire object

const person = { name : 'Tom' , age : 24 } const personProxy = new Proxy (person, { get (target, prop) { //1. For the value operation of the object property, add the default value, and finally return the property value return target[prop]? Target[prop]: 'default' }, set (target, prop, value) { //Tips: The code prompted by vscode is not what we need, just press the Esc key //2. Assign value to object properties, add verification and exception handling if (prop === 'age' ) { if (! Number .isInteger(value)) { throw new Error ( 'this value must be a integer' ) } } //3. Assign values to object properties target[prop] = value } }) personProxy.age = '20' log(personProxy.name) log(personProxy.xxx) Copy code

2,

Proxy
versus
Object.defineProperty
Compared
Object.defineProperty
It only supports hijacking the reading and writing of the object, and it is an intrusive writing method that requires the object to be modified.
Proxy
It is to supervise the entire object,
Proxy
Hijack the entire object in a non-invasive way.

const person = { name : 'Tom' , age : 24 } const personProxy = new Proxy (person, { set (target, prop, value) { target[prop] = value }, deleteProperty (target, prop) { console .log( 'delete' , prop) delete target[prop] } }) delete personProxy.age = personProxy.gender 'man' log (Person) //{name: 'Tom', Gender: 'man'} copy the code

Proxy
For more friendly monitoring of array operations, in the past, array monitoring was implemented by rewriting the array (vue2+)

const list = [] const listProxy = new Proxy (list, { set (target, prop, value) { target[prop] = value return true //mark the array element added successfully } }) listProxy.push( '11' ) log (List) //[ '. 11'] duplicated code

3. In addition to the commonly used attribute operations above, there are other operations, as follows:

8. Reflect static class

The meaning of birth:

Reflect
The static class provides a unified method of manipulating objects. In the past, the way we manipulate objects was very complicated, such as
delete
,
in
,
Object.keys()
, It will be discarded in the future.

const person = { name : 'Tom' , age : 24 } log( 'name' in person) //Determine whether an object has a certain attribute, which is exactly the same as the function of the in operator. log( Reflect .has(person, 'name' )) log( delete person.name) //As the delete operator of the function, it is equivalent to executing delete target[name] log( Reflect .deleteProperty(person, 'name' )) log( Object .keys(person)) //returns an array containing all its own properties (not including inherited properties). (Similar to Object.keys (), but does not affect by the enumerable). Log ( Reflect .ownKeys (the Person)) Copy the code

Can be modified before

Proxy
Methods of obtaining object properties

const personProxy = new Proxy (person, { get (target, prop, value) { log( 'watch ...' ) return Reflect .get(target, prop) } }) console .log(personProxy.age) Copy code

In addition to the above commonly used attribute operations, there are other operations, as follows:

9. Promise object

Slightly, refer to handwritten promise

10. class keywords

The meaning of birth: let

Javascript
The definition of the class is simple and easy to understand.
1. In the past, we defined a class by using a constructor, as follows:

function Person ( value ) { this .name = value } Person.create = function ( value ) { //ES5 defines the static method of the class return new Person(value) } Person.prototype.say = function () { log( `hi, my name is ${ this .name} ` ) } //const person = new Person() const person = Person.create( 'Tom' ) person.say() Copy code

2. Now we use the class keyword to define the class, which is concise and easy to understand

class Person { constructor ( value ) { this .name = value } say () { log( `hi, my name is ${ this .name} ` ) } static create (value) { //ES6 defines the static method of the class return new Person(value) } } //const person = new Person('Tom') const person = Person.create( 'Tom' ) person.say() Copy code

11. Inheritance of extends class

The meaning of birth: to make class inheritance more concise and easy to understand.

class Person { constructor ( value ) { this .name = value } say () { log( `hi, my name is ${ this .name} ` ) } } class Student extends Person { constructor ( name, number ) { super (name)//The super object always points to the parent class, calling it means calling the parent class constructor this .number = number } hello () { super .say() log( `my school number is ${ this .number} ` ) } } //extends class inheritance, compared to the prototype inheritance ES5, more concise and understandable const Student = new new Student ( 'Jack' , 101 ) Console .log (student.hello ()) copying the code

12. Set data structure

The meaning of its birth: Set objects allow you to store any type of unique value, whether it is a primitive value or an object reference.

const list = new Set () //There are no duplicate elements in the data set list.add( 1 ).add( 2 ).add( 2 ).add( 4 ) //add method returns the set itself, so it can be chained Call for (i of list) { log(i) } log(list.delete( 4 )) log(list.size) log(list.has( 4 )) //A common scenario is to remove duplicates from an array const arr = [ 1 , 1 , 4 , 4 , 5 , 6 ] log( Array .from( new Set (arr))) log ([... new new the Set (arr)]) Copy the code

13. Map data structure

The meaning of birth: a collection of key-value pairs in the strict sense can use any data type as the key.
1. In the past, multiple data types were used as key-value objects

const obj1 = { [ 123 ]: '123' , [ true ]: 'true' , [{ a : 1 }]: 'a' , [{ b : 1 }]: 'b' , } log ( Object .keys (OBJ1)) //[ '123', 'to true', '[Object Object]'] log (OBJ1 [ '[Object Object]' ]) //B duplicated code

Problem: The key value is

Object.prototype.toString.call(key)
Convert to string
2,
ES6
Collection definition of key-value pairs

const obj2 = new Map () const tom = { name : 'tom' } obj2.set(tom, 'c' ) log(obj2) obj2.forEach( ( value, key ) => log(value, key)) log(obj2.get(tom)) log(obj2.has(tom)) log(obj2.delete(tom)) log(obj2.clear()) Copy code

14. Symbol basic data types

1. In the past, when different files repeatedly defined the same attribute of the global object, there was an overwriting problem. The following simulates different files.

const cache = {} /* -----------------a.js--------------------- */ cache[ 'foo' ] = '111' /* ----------------b.js--------------------- */ cache[ 'foo' ] = '222' log (Cache) //{foo: '222'} copy the code

2. The Symbol type can define constants and add a description of Symbol data

const s = Symbol ( 'foo' ) log( typeof s) //Symbol log( Symbol ( 'foo' )) //Symbol(foo) adds a description of Symbol data log( Symbol ( 'bar' )) log ( the Symbol ( 'FPP' )) copying the code

3. Define the private properties of the object, which were previously agreed upon: _name:'Tom', unreliable

const name = Symbol ( 'name' ) const person = { [name]: 'Tom' , //3. Define the private properties of the object, which were previously agreed upon: _name:'Tom' say () { log( ` ${ this [name]} ` ) } } log(person.name) //undefined log(person.say()) //Tom copy the code

Symbol
The main function of type data is to add a unique attribute name to the object.
4. Comparison of Symbol type

log( Symbol () === Symbol (), Symbol ( 'foo' ) === Symbol ( 'foo' )) //false false log( Symbol .for( 'foo' ) === Symbol .for( ' foo' )) //true //Symbol maintains a descriptor-to-Symbol mapping table log( Symbol .for( true ) === Symbol .for( 'true' )) //true //Symbol.for( ) internally calls the toString () method to copy the code

5.

Symbol()
Properties are more suitable as private properties of objects

const obj1 = { [ Symbol ()]: 'Symbol value' , [ Symbol ()]: 'Symbol value' , foo : 'value' } for (key in obj1) { //foo log(key) } log( Object .keys(obj1)) //['foo'] log( JSON .stringify(obj1)) //{"foo":"value"} //Get Object of all types of keys Symbol log ( Object .getOwnPropertySymbols (OBJ1)) //[Symbol (), Symbol ()] Copy the code

for...in
,
Object.keys()
,
JSON.stringify()
And so on, you can't get the attributes of the Symbol type, and it proves that the Symbol type is more suitable as the private attribute of the object.

15. ES6 iterable interface

Birth meaning: theoretically

for...of
Can traverse any kind of data structure (array, pseudo-array,
Set
,
Map
, Etc.)
1.
JavaScript
Loop traversal in

const list1 = [ 1 , 2 , 3 , 4 , 5 ] //const list1 = new Set([1, 2, 3, 4, 5]) for ( const value of list1) { log(value) if (value> 2 ) { break } } //list1.some() //list1.every() const list2 = new Map () list2.set({ a : 1 }, 1 ) list2.set({ b : 2 }, 2 ) for ( const [key, value] of list2) { log(key, value) } Copy code

2. Contrast

forEach
with
for...of

list2.forEach ( Item => log (Item)) //out of the loop can not be duplicated code

3. The data interface contains an iterable interface-Symbol (Symbol.iterator)

//const arr = [1, 2, 3, 4] const arr = new Set ([ 1 , 2 , 3 , 4 ]) log(arr[ Symbol .iterator]) //[Function: values] an iterable function is defined on the array prototype object, and the return object log(arr[ Symbol .iterator]().next()) //{value: 1, done: false} calling the object next () method of copying the code

4. How to implement the iterable interface of the object, using the iterator pattern (design pattern)

const obj2 = { study: [' ', ' ', ' '], life: [' ', ' ', ' '], work: [' '], [Symbol.iterator] () { const list = Object.entries(obj2) let index = 0 return { next () { return { value: list[index], done: index++ >= list.length } } } } } // [Symbol.iterator] for...of for (const [key, value] of obj2) { log(key, value) }

ES6

1

function* fn () { log('111...') yield 100 log('222...') yield 200 } const result = fn() log(result.next()) //111... { value: 100, done: false } log(result.next()) //111... { value: 200, done: false } log(result.next()) // { value: undefined, done: true }

2

function* createIdMaker () { let id = 1 while (true) { yield id++ } } const maker = createIdMaker() log(maker.next().value) // log(maker.next().value) log(maker.next().value)

3

const obj2 = { study: [' ', ' ', ' '], life: [' ', ' ', ' '], work: [' '], [Symbol.iterator]: function* () { const list = Object.entries(obj2) for (const item of list) { yield item } } } for (const item of obj2) { log(item) }

ES7 ES8

1

Object.values()
Object.entries()
Object.getOwnPropertyDescriptors

const p1 = { firsetName: 'Yon', lastName: 'zhang', get fullName () { return this.firsetName + ' ' + this.lastName } } log(Object.values(p1)) //[ 'Yon', 'zhang', 'Yon zhang' ] log(Object.entries(p1)) // const descriptors = Object.getOwnPropertyDescriptors(p1) log(descriptors) const p2 = Object.defineProperties({}, descriptors) p2.firsetName = 'ton' log(p2.fullName)

2

padEnd()
padStart()

const books = { html: 3, css: 10, javaScript: 103, } for (const [key, value] of Object.entries(books)) { log(`${key.padEnd(16, '-')} | ${value.toString().padStart(3, '0')}`) } //html------------ | 003 //css------------- | 010 //javaScript------ | 103