In today’s rapid development of the front-end, if you can’t keep learning will soon be eliminated. I would like to share my knowledge of ES6. The article is a bit long and I hope it will be helpful to you. Make a little progress every day.

ECMAScript and JavaScript

JavaScript is actually an extension of ECMAScript, which provides only the most basic syntax (conventions on how code should be written, such as how variables and functions should be defined, how loop statements should be implemented, etc.). JavaScript implements and extends the ECMAScript standard, allowing you to manipulate the DOM and BOM in the browser, read and write files in the Node environment, and so on.

In the browser environment, JavaScript = ECMAScript + Web APIs

JavaScript = ECMAScript + Node APIs [fs/net/etc.]

Second, ECMAScript development process

New features of ECMAScript 2015

Enhancements to existing syntax to make it easier to use (e.g., deconstruction, expansion, parameter defaults, template strings, etc.)

Fix some problems or bugs in the original syntax (e.g., let, const block-level scope)

New objects, new methods, new functionality (such as Promises, proxies, object.assign methods, etc.)

New data types and data structures (such as symbol, map, set, and so on)

1. Let and const

1. Use and precautions of LET

<1> Let is used like var, but the declared variable is only valid within the code block in which the let command is executed.

{
  let a = 10;
  var b = 1;
}

console.log(a) // ReferenceError: a is not defined.
console.log(b) // 1
Copy the code

<2> The “variable promotion” phenomenon occurs in the var command, that is, the variable can be used before the declaration and its value is undefined. The let command changes the syntactic behavior by declaring variables that must be used after the declaration or an error will be reported.

// var case console.log(foo); Var foo = 2; // let's case console.log(bar); // ReferenceError let bar = 2;Copy the code

<3> Within the code block, the variable is not available until it is declared using the let command. This is grammatically called a temporary dead zone (TDZ).

If (true) {// TMP = 'ABC '; // ReferenceError console.log(tmp); // ReferenceError let tmp; // TDZ end console.log(TMP); // undefined tmp = 123; console.log(tmp); / / 123}Copy the code

<4> LET does not allow the same variable to be declared twice in the same scope.

2. Use and precautions of const

<1>const Declares a read-only constant. Once declared, the value of a constant cannot be changed. It must be initialized immediately and cannot be left for later assignment.

Ps: Here cannot modify refers to the memory address stored, modify the constant attribute member is allowed.

const foo;
// SyntaxError: Missing initializer in const declaration
Copy the code

The <2> scope is the same as the let command: it is valid only in the block-level scope in which the declaration is made.

Constants declared by the <3>const command are also unpromoted and have temporary dead zones that can only be used after the declared position.

Arrow function

Arrow functions

Arrow functions and this (arrow functions have no mechanism for this, so arrow functions do not change the direction of this)

const person = { name: 'zhangsan', // sayHi: function() { // console.log(`hi, my name is ${this.name}`) // } sayHi: () => { console.log(`hi, my name is ${this.name}`) }, sayHiAsync: function() { // const _this = this // setTimeout(() => { // console.log(_this.name) // }, 1000) // Use _this = this in work, SetTimeout (() => {console.log(this.name)}, 1000)}} // person.sayhi () // hi, my name is zhangsan person.sayHi() // hi, my name is undefined person.sayHiAsync() // zhangsanCopy the code

3. Class = Class

// Create class Person {// constructor(name) {this.name = name} // instance method say() {console.log(' my name is ${this.name}`) } } const p = new Person('tom') p.say() // my name is tomCopy the code

Static member

// Create class Person {// constructor(name) {this.name = name} // instance method say() {console.log(' my name is ${this.name} ')} // static method mounted on class, Const p = person.create ('jack') p.say() static create(name) {return new Person(name)}} const p = person.create ('jack') p.say() // my name is jackCopy the code

Class extends

Class Person {constructor(name) {this.name = name} say() {console.log(' my name is ${this.name} ')} Class Student extends Person {constructor(name, number) {// super always points to the parent class. Super (name) this.number = number} hello () {// super always refers to the parent class, Say (name) console.log(' my school number is ${this.number} ')}} const p = new Student('jack', '11') p.hello()Copy the code

4, Promise

Promise is a better asynchronous programming solution that solves the problem of deep nested callback functions in traditional asynchronous programming. For details, see

5, Generators

Avoid deep nested callbacks in asynchronous programming and provide a better asynchronous programming solution

The Generator Generator

Function * foo() {console.log(111111); // Yield pause is similar to return, Yield 1000 console.log(2222222) yield 2000} const fn = new foo() console.log(fn.next()) // 111111 // {value: 1000, done: false} console.log(fn.next()) // 2222222 // {value: 2000, done: false} console.log(fn.next()) // {value: undefined, done: true}Copy the code

Generator application Generator

Function * createMaker() {let id = 1 while(true) {yield ID ++}} const addID = createMaker() console.log(addID.next().value) console.log(addID.next().value)Copy the code
// 2, implement iterator method const obj = {life: [' eat ', 'sleep ',' play '], work: [' HTML ', 'CSS ', 'javascript'], learn: [Symbol. Iterator], [Symbol. Iterator]: function * () { const all = [...this.life, ...this.work, ...this.learn] for (const item of all) { yield item } } } for (const item of obj) { console.log(item) }Copy the code

6, Modules

ES Modules Language level modularity standards, which will be covered in modular development

7. Template literals

Template string literals (newline support, interpolation support)

const name = 'zhangsan'
const msg = `hello, ${name}! --- ${ 1+ 2 } === ${Math.random()}`
console.log(msg) 		// hello, zhangsan! --- 3 === 0.24367109177674284
Copy the code

Tagged templates (To use tag functions, you must define tag functions first, which are used to process template strings)

// const STR = console.log 'hello world' // ['hello world'] const name = 'zhangsan' const age = 18 Const sex = 1 // The first argument received by the tag function is an array of all the static content, Function tagFun(STR, name, age, sex) {// console.log(STR, name, age, sex) {// console.log(STR, name, age, sex) STR [0] + name + STR [1] + age + STR [2] + sex} const r = tagFun 'hello, ${name}, year is ${age} sex is ${sex}` // [ 'hello, ', ', year is ', ' sex is ', '' ] zhangsan 18 1 console.log(r) // hello, zhangsan, year is 18 sex is 1Copy the code

The extension methods of the string (includes/startsWith/endsWith)

const str = "Error: foo is not defined."
console.log(str.startsWith('Error'))		// true
console.log(str.endsWith('.'))		// true
console.log(str.includes('is'))		// true
Copy the code

8. Default parameters

Parameter Default Value Default parameters

If there are more than one parameter, the parameter with the default value is placed last

// function fun (enable) { // enable = enable === undefined ? true : Function fun(enable = true) {// function fun(enable = true) {// function fun(enable = true) {// Console.log (enable) //} // fun() // true // fun(1) // 1 // If there are multiple arguments, Function fun(a, enable = true) {console.log('a', a, 'enable', enable)} fun(1, false) // a 1 enable falseCopy the code

9. Object literals are enhanced

Object literals enhance Enhanced Object Literals

Const name = "zhangsan" const obj = {// name: name, name, age: 18, // methods: Function () {// console.log(1111) //} methods() {// function() console.log(1111)}, // math.random (): 123, // Calculate attribute name [math.random ()]: 123} console.log(obj)Copy the code

The Object extension method object.assign

const target = { a: 1, b: 2 } const obj1 = { c: 3, d: 4 } const obj2 ={ a: 11, e: 5} // object. assign Receives multiple objects. The first Object is the target Object. Const r = object. assign(target, obj1, obj2) console.log(target) //{a: 11, b: 2, c: 3, d: 4, e: 5} console.log(target === r) // true // Use object. assign to copy objects, Const newObj = object. assign({}, r) newobj. a = 123 console.log(r) // {a: 11, b: 2, C: 3, d: 4, e: 5 } console.log(newObj) // { a: 123, b: 2, c: 3, d: 4, e: 5 }Copy the code

Object extension method object.is (used to determine if two values are equal)

console.log( // 0 == false // true // 0 === false // false // +0 === -0 // true // NaN == NaN // false // Object.is(+0, -0) // false object. is(NaN, NaN) // trueCopy the code

10. Deconstruct distribution

Destructuring array (extract by array position)

Const arr = [1, 2, 3, 4] const [a, b, c, d] = arr Const [f,...g] = arr // If there is no value in the array return undefined, You can also give default values const [,,,, h, I = 'default'] = arr console.log(a, b, c, d) // 1 2 3 4 console.log(e) // 3 console.log(f) // 1 console.log(g) // [2, 3, 4] console.log(h) // undefined console.log(i) // defaultCopy the code

Object Destructuring (extraction based on the object’s property name)

Object deconstruction, like arrays, uses undefined for unmatched members, which can also be given a default value

const obj = { name: 'zhangsan', age: 18} const {name} = obj console.log(name) // zhangsan // use rename to resolve naming conflicts const {name: New_name} = obj console.log(new_name) // zhangsan // can continue to give default values after renaming const {name: new_name2 = 'lisi' } = obj console.log(new_name2) // zhangsanCopy the code

11. Expand operators

Rest Parameters

Function fn() {console.log(arguments)} fn(1, 2, 3) // [arguments] {'0': 1, '1': 2, '2': 2 3 } function fn2 (a, ... Arg) {// Use the expansion operator to get an array instead of Arguments. Log (arg)} fn2(1, 2, 3) // [1, 2, 3]Copy the code

Expand array Spread

Const arr = [' a ', 'b', 'c'] / / the console log (/ / arr [0], / / arr [1], / / arr) [2] / / / / for parameters are not fixed, // We could have used apply, and the first argument to apply was this, Console.log. apply(console, arr) // Use the expansion operator to make console.log(... arr)Copy the code

12, for… Of circulation

Ordinary for loop, suitable for traversing groups of numbers; For in is suitable for traversing key-value pairs; There are also many functional traversal methods, such as the forEach method for array objects, which have some limitations. ES6 introduces the for of loop as a uniform way to iterate over all data results

Iterable interface Iterable interface for… The premise of

// All are for... Const arr = ['a', 'b', const arr = ['a', 'b', 'c'] const iterator = arr[Symbol.iterator]() console.log(iterator.next()) console.log(iterator.next()) console.log(iterator.next()) console.log(iterator.next()) console.log(iterator.next()) const arr2 = new Set([1, 2, 3]) const iterator2 = arr2[Symbol.iterator]() console.log(iterator2.next()) console.log(iterator2.next()) console.log(iterator2.next()) console.log(iterator2.next())Copy the code

Implement the Iterable interface Iterable

// The next method returns an object with two attribute members, one value, A done const obj = {name: 'zhagnsan', age: 20, sex: 'male ', [Symbol. Iterator]: function () { let index = 0 const arr = [this.name, this.age, this.sex] return { next () { const result = { value: arr[index], done: index >= arr.length } index++ return result } } } } for (const item of obj) { console.log(item) }Copy the code

The Iterator pattern Iterator

Const obj = {life: [' eat ', 'sleep ',' play '], learn: {life: [' eat ', 'sleep ',' play '], learn: [' HTML ', 'CSS', 'javascript'], work: [' move brick ', 'tea', 'go to the toilet'], [Symbol. The iterator] : function () { let index = 0 const all = [...this.life, ...this.learn, ...this.work] return { next() { const result = { value: all[index], done: index >= all.length } index++ return result } } } } for (const item of obj) { console.log(item) }Copy the code

Map and Set

Set data structure [Set internal members are not allowed to duplicate]

Const arr = new Set() // add returns the collection itself, Add (1).add(2).add(3).add(4).add(2) // console.log(arr) // You can loop through // arr.foreach (I => console.log(I)) // for (let I of arr) console.log(I) // size query length, has query whether the specified value is included, delete delete specified value, Log (arr.size) console.log(arr.has(100)) console.log(arr.delete(1)) console.log(arr) arr.clear() Console. log(arr) const array = [1, 2, 3, 2, 5, 3] // const r = Array.from(new Set(array)) const r = [...new Set(array)] console.log(r)Copy the code

Map data structures [similar to objects, which are essentially collections of key-value pairs]

const obj = [] obj[123] = 'value' obj[true] = 'value' obj[{a: 1}] = 'value' console.log(object.keys (obj)) // ["123", "true", "[Object Object]"] are converted to strings by toString(). Const m = new map () const Tom = {name: 'Tom'} const jack = {name: 'jack'} m.et (Tom, 90) m.et (Jack, 96) console.log(m) Map instances also have has, Delete, and clear methods m.haas (Tom) m.Delte (Jack) m.clear() console.log(m).Copy the code

14, the Proxy

Proxy Proxy object (a gatekeeper that sets access proxies for objects)

ES6 natively provides a Proxy constructor to generate a Proxy instance.

var proxy = new Proxy(target, handler);
Copy the code

All uses of Proxy objects are in this form, except for the handler arguments. The new Proxy() parameter represents the generation of a Proxy instance, the target parameter represents the target object to intercept, and the handler parameter is also an object used to customize the interception behavior

<1>get()

The get method intercepts a read of a property and can take three parameters, the target object, the property name, and the proxy instance itself (strictly speaking, the object against which the action is directed), the last of which is optional.

Var person = {name: "name"}; var proxy = new Proxy(person, { get: function(target, propKey) { if (propKey in target) { return target[propKey]; } else { throw new ReferenceError("Prop name \"" + propKey + "\" does not exist."); }}}); Proxy. name // "John" proxy.age // Throws an errorCopy the code

In the code above, Proxy takes two arguments as a constructor. The first argument is the target object (in this case, the Person object) that the operation would have accessed without Proxy intervention. The second argument is a configuration object that needs to provide a corresponding handler function for each propped operation that intercepts the corresponding operation

<2>set()

The set method is used to intercept the assignment of an attribute. It can take four parameters: the target object, the attribute name, the attribute value, and the Proxy instance itself. The last parameter is optional.

Given that the Person object has an age attribute, which should be an integer not greater than 200, you can use Proxy to ensure that the value of the age attribute meets the requirements.

let validator = { set: function(obj, prop, value) { if (prop === 'age') { if (! Number.isInteger(value)) { throw new TypeError('The age is not an integer'); } if (value > 200) { throw new RangeError('The age seems invalid'); // Obj [prop] = value; obj[prop] = value; }}; let person = new Proxy({}, validator); person.age = 100; Person. Age // 100 person. Age = 'young' // personCopy the code

<3>deleteProperty()

The deleteProperty method intercepts the DELETE operation. If the method throws an error or returns false, the current property cannot be deleted by the delete command.

var handler = { deleteProperty (target, key) { invariant(key, 'delete'); delete target[key]; return true; }}; function invariant (key, action) { if (key[0] === '_') { throw new Error(`Invalid attempt to ${action} private "${key}" property`); } } var target = { _prop: 'foo' }; var proxy = new Proxy(target, handler); delete proxy._prop // Error: Invalid attempt to delete private "_prop" propertyCopy the code

In the code above, the deleteProperty method intercepts the delete operator, and deleting an attribute whose first character is an underscore raises an error

Proxy vs. Object.defineProperty()

15 and Reflect

1. A static class with a unified object manipulation API that encapsulates a set of low-level operations on objects

2. The name of the Reflect method is exactly the same as the method member that handles the object in the Proxy object

// Reflect member method is the default implementation of Proxy handling objects const obj = {foo: 123, bar: 456 } const p = new Proxy(obj, { get(target, propert) { return Reflect.get(target, propert) } }) console.log(p.foo) // 123Copy the code

3. Reflect’s significance: It provides a unified set of apis for manipulating objects

16, Symbol,

A new primitive data type that represents a unique value, the main function of which is to add unique attribute names to objects

Symbol const s = Symbol() console.log(s) // Symbol() console.log(typeof s) // Symbol // (Symbol() === Symbol()) // false // As the description text console.log(Symbol('foo')) // Symbol(foo) console.log(Symbol('bar')) // Symbol(bar) ///4 const obj = {} obj[Symbol()] = '123' obj[Symbol()] = '456' console.log(obj) // { [Symbol()]: '123', [Symbol()]: Const obj2 = {[Symbol()]: '111'} console.log(obj2) // {[Symbol()]: Const name = Symbol() const person = {[name]: const person = {[name]; 'Tom ', say() {console.log(this[name])}} // Person. Say () in b.js // TomCopy the code

Fourth, ECMAScript 2016

1. The includes method of an array instance object, which checks if the array contains a specified element, becomes simpler

const arr = ['foo', 1, NaN, False] // Traditional check console.log(arr.indexof ('foo')) // 0 console.log(arr.indexof ('bar')) // -1 console.log(arr.indexof (NaN)) Log (arr.indexof (false)) // 3 // Check console.log(arr.includes('foo')) // true Console. log(arr.includes('bar')) // false console.log(arr.includes(NaN)) // true -- NaN can be detected console.log(arr.includes(false)) // trueCopy the code

2. Exponential operators

Console. log(math.pow (2, 10)) console.log(2 ** 10) // Use exponential operator to find 2 to the 10th powerCopy the code

Five, the ECMAScript 2017

1, the three Object extension methods [Object. The value (), Object. The entries (), Object. GetOwnPropertyDescriptors ().

const obj = { foo: 'v1', bar: 'v2'} // 1, like object.keys (), Object.values() returns an array of Object values console.log(object.values (obj)) // ['v1', The 'v2'] // 2, object.entries () method returns an array of key pairs from the Object console.log(object.entries (obj)) // [['foo', 'v1'], ['bar', 'v2' ] ] for (let [key, value] of Object.entries(obj)) { console.log(key, Value)} // foo v1 // bar v2 // Convert entries to Map console.log(new Map(object.entries (obj))) // Map(2) {'foo' => 'v1', 'bar' = > 'v2} / / 3, the Object getOwnPropertyDescriptors () to get a full description of information in the Object / / after ES5 Object to define getter and setter attribute, Const p1 = {firstName: 'lei', lastName: const p1 = {firstName: 'lei', lastName: 'wang', get fullName() { return this.firstName + ' ' + this.lastName } } // const p2 = Object.assign({}, P1) // p2.firstname = 'hua' // console.log(p2.fullname) // lei wang --fullName is copied as a normal string const des = Object.getOwnPropertyDescriptors(p1) const p2 = Object.defineProperties({}, des) p2.firstName = 'hua' console.log(p2.fullName) // hua wangCopy the code

2, two string padding method [padEnd, padStart]

const books = { html: 5, css: 10, javascript: } // For the length of its output string, For (let [name, count] of object.entries (books)) {console.log(' ${name.padend (16, '- ')} | ${count.toString().padStart(3, '0')}`) } // html- - - - - - | 005 // css- - - - - - - | 010 // javascript- - - | 015Copy the code

Add a closing comma to the last part of a function argument list.

4, Aysnc/Await [essentially grammar candy of promise]