1. ES2015 (ES6)

1. Let and block-level scope

console.log(a)//undefined
var a = 1
Copy the code

Let declares variables, but there is no variable promotion

console.log(a)// a is not defined
let a = 1
Copy the code

Js includes global scope, function scope, and block-level scope. Let and const can only be accessed inside the block-level scope (which is also a closure mechanism). Let’s request that we declare variables in use first!

for (var i = 0; i < 3; I ++) {var I = 'foo' // (1) let I = 'foo' // (2) console.log(I) // (1) prints only one foo because I is confused with (2) prints three foo}Copy the code

Familiar problems

for (var i = 0; i < 3; i++) {
    setTimeout(() => {
        console.log(i)//3 3 3
    })
}
Copy the code

To solve

for (let i = 0; i < 3; i++) {
    setTimeout(() => {
        console.log(i)//0 1 2
    })
}
Copy the code

2. const

const name = 'lcj'
name = 'xyz'//error
Copy the code
const name
name = 'xyz'//error
Copy the code

Const must be declared and assigned to const name = ‘LCJ’ const constants that cannot be modified once they are defined separately

const obj = {}
obj = { x: 1 }//error
Copy the code
Const obj = {} obj. Name = 'xyz'// yesCopy the code

Const can modify constant attributes, but not memory pointing!

Reasonable declaration specification: main const, with let, no var!

3. Array deconstruction

Const arr = [100, 200, 300] const [a, b, c] = arr console.log(a, b, c)//100, 200, 300  const [, , d] = arr console.log(d)// 300 //... Const [e,...rest] = arr console.log(rest)//[200, 300] // Assign from the first const [f] = arr console.log(f) //undefined const [g, h, I, j] = arr console.log(j)//undefined const [g, h, I, j] = arr console.log(j) n = '123'] = arr console.log(n)//123 const path = 'foo/bar/baz' const [, rootdir] = path.split('/') console.log(rootdir)//barCopy the code

4. Deconstruction of objects

Arrays are deconstructed by subscript, and objects are deconstructed by attribute name

const obj = { name: 'lcj', age: 18 }
const { name } = obj
console.log(name)//lcj
Copy the code

This raises the question, what happens when we use object deconstruction to take a name and declare a name conflict

const obj = { name: 'lcj', age: 18 }
const { name } = obj
const name = 'abc'
console.log(name)//error
Copy the code

Workaround: Rename object properties

const obj = { name: 'lcj', age: 18 }
const { name: myName = 'daisy' } = obj
const name = 'abc'
console.log(name)//abc
console.log(myName)//lcj
Copy the code

Const {name: myName = ‘Daisy’} = obj [= ‘Daisy’] Name The variable name in object obj, myName is our new name. Print myName to get the result.

const { log } = console
console.log(log)//[Function: bound consoleCall]
log('123')//123
Copy the code

5. Template string

Const STR = 'hello world' console.log(STR)// Hello world // To print 'in the template string, use the escape character \ const str2 =' hello,this is a \ 'string' Console. log(str2)//hello,this is a string Const str3 = 'hello' console.log(str3) const name = 'LCJ' const str4 = 'hey,${name} Console. log(str4)//hey, LCJ // Basic calculations const str5 = 'hey,${1 + 2}' console.log(str5)//hey,3Copy the code

6. Template string tag function

const str = console.log`hello world`
console.log(str)//[ 'hello world' ]
Copy the code

Before defining the template string, add a tag, such as const STR = console. logHello world, where tag is a tag function (a special function)

const name = 'lcj'
const gender = false
function myTag(arr, name, gender) {
    console.log(arr)//[ 'hey,', ' is a ', '.' ]
    let sex = gender ? 'man' : 'woman'
    return arr[0] + name + arr[1] + sex + arr[2]
}
const res = myTag`hey,${name} is a ${gender}.`
console.log(res)//hey,lcj is a woman.
Copy the code

7. String extension methods

StartsWith: determines whether to start with, endsWith: determines whether to end with, and includes: determines whether to include

const msg = `I am a girl.`
console.log(msg.startsWith('I'))//true
console.log(msg.startsWith('a'))//false
console.log(msg.endsWith('.'))//true
console.log(msg.endsWith('l'))//false
console.log(msg.includes('am'))//true
console.log(msg.includes('am ab'))//false
Copy the code

8. Default values

* * * parameter is normal use, so there is no will default to true * * * the function foo (enable) {enable = enable | | true / / (1) enable enable = = = = undefined? true : enable//(2) console.log(enable) } foo()//true foo(false)//(1)true (2)falseCopy the code

Foo (false) still returns true, so it should be changed to (2), new in ES6

function foo(enable = true) {
    console.log(enable)
}
foo()//true
foo(false)//false
Copy the code

9. Remaining parameters

function foo() {
    console.log(arguments)//[Arguments] { '0': 1, '1': 2, '2': 3, '3': 4 }
}
foo(1, 2, 3, 4)
Copy the code

We use arguments for an unknown number of arguments, which is actually a pseudo-array

function foo(... arg) { console.log(arg)//[ 1, 2, 3, 4 ] } foo(1, 2, 3, 4)Copy the code

. Arg can only appear in the last bit of a parameter and can only be used once. Receives all arguments from the current location as an array

function foo(a, ... arg) { console.log(a)//1 console.log(arg)//[ 2, 3, 4 ] } foo(1, 2, 3, 4)Copy the code

10. Expand the array

Const arr = ['foo', 'bar', 'ABC '] console.log. Apply (console, arr)//foo bar ABC arr)//foo bar abcCopy the code

. Automatically passes the members of the array to the parameter list

11. Arrow function

The arrow function code is shorter and easier to read, with a list of arguments to the left of the arrow and the function body to the right

const inc = (m,n)=>m+n
Copy the code

12. Arrow function with this

The arrow function does not change the this pointer

const person={ name:'tom', / / * * * * * * the original writing / / sayHi: function () {/ / console log (` hi, my name is ${this. The name} `) / / hi, my name is Tom / /} es6 / / * * * * * * sayHi:()=>{ // console.log(this)//{} console.log(`hi,my name is ${this.name}`)//hi,my name is undefined }, SayHiAsync :function(){const that = this // console.log(this)// sayHiAsync:function(){const that = this // console.log(this)//{name: 'Tom ',sayHi:... } // setTimeout(function(){ // console.log(this)//Timeout {... } // console.log(this.name)//undefined // console.log(that.name)//tom // },1000) // *** es6 *** setTimeout(()=>{ console.log(this.name)//tom }) } } person.sayHi() person.sayHiAsync()Copy the code

There is no mechanism for this in the arrow function, so this is the same as this outside the method

13. Enhancement of object literals

Const bar = '123' const obj = {name:' LCJ ', //bar:bar Function (){console.log(123456) //} method(){console.log(this)//{name: 'LCJ ', bar: '123', method: [Function: Method]}//this points to the current object console.log(123456)}// ES6 dynamic add attribute name [math.random ()]:1, [1+2]:2 [bar]:3} console.log(obj) 'LCJ ', bar: '123', method: [Function: method]} obj.method()//123456 //*** obj[math.random ()]=1Copy the code

14. Object.assign

Copies properties from multiple source objects to a target object. If the object objects have the same properties, the properties of the source object overwrite the properties of the target object.

const s1 ={ a:123, b:123 } const s2 ={ b:567, d:567 } const target = { a:456, c:456 } const res = Object.assign(target,s1) console.log(res)//{ a: 123, c: 456, b: 123 } const res2 = Object.assign(target,s1,s2) console.log(res2)//{ a: 123, c: 456, b: 567, d: 567} console.log(res === target)//true indicates oneCopy the code

Back cover front!

function func(obj){
 obj.name = 'func obj'
 console.log(obj)//{ name: 'func obj' }
}
const obj = {name:'global obj'}
func(obj)
console.log(obj)//{ name: 'func obj' }
Copy the code

Because obj refers to the same memory address, it changes the property value internally and also changes the value externally. Internally generates a brand new property!

function func(obj){
 const funcObj = Object.assign({},obj)
 funcObj.name = 'funcObj obj'
 console.log(funcObj)//{ name: 'funcObj obj' }
}
const obj = {name:'global obj'}
func(obj)
console.log(obj)//{ name: 'func obj' }
Copy the code

The Object. Assign parameter is an Object. If it is not an Object, it will be converted to an Object.

Object.assign(undefined)//error
Object.assign(null)//error
Copy the code

Other types of values (that is, values, strings, and booleans) do not take the first argument and will not report an error. However, none of the values have any effect except that the string is copied into the target object as an array. In the following code, v1, v2, v3 are string, Boolean, and number, respectively. The result is that only the string is merged into the target object (in the form of a character array), and both the value and the Boolean are ignored. This is because only string wrapped objects produce enumerable properties.

const v1 = 'abc';
const v2 = true;
const v3 = 10;
const obj = Object.assign({}, v1, v2, v3);
console.log(obj); // { "0": "a", "1": "b", "2": "c" }
Copy the code

Common use

Add attributes to objects — Add x and y attributes to the Object instance of the Point class using the Object.assign method.

class Point { constructor(x, y) { Object.assign(this, {x, y}); }}Copy the code

2. Object adding method

Prototype, {someMethod(arg1, arg2) {···}, anotherMethod() {··· ·}}); / / equivalent to the following writing SomeClass. Prototype. SomeMethod = function (arg1, arg2) {...}. SomeClass. Prototype. AnotherMethod = function () {...}.Copy the code

3. Clone objects

function clone(origin) {
  return Object.assign({}, origin);
}
Copy the code

In this way, only the value of the original object can be cloned, not its inherited value. If you want to maintain the inheritance chain, you can use the following code.

function clone(origin) {
  let originProto = Object.getPrototypeOf(origin);
  return Object.assign(Object.create(originProto), origin);
}
Copy the code

4. Merge multiple objects

const merge = (target, ... sources) => Object.assign(target, ... sources);Copy the code

5. Specify default values for the properties

const DEFAULTS = {
  logLevel: 0,
  outputFormat: 'html'
};

function processContent(options) {
  options = Object.assign({}, DEFAULTS, options);
  console.log(options);
  // ...
}
Copy the code

The DEFAULTS object is the default value, and the Options object is the user-supplied parameter. The object. assign method merges DEFAULTS and options into a new Object. If they have the same property, the value of the option property overrides the value of the DEFAULTS property.

15. object.is

Used to determine whether two values are equal. We used ==(which automatically converts data types) or ===(third-order strict comparison) to determine if two values are equal.

/ / = = type conversion will be carried out in the console. The log (0 = = false) / / true / / = = = strictly, but unable to distinguish between + 0 and 0, NAN console.log(0===false)//false console.log(+0===-0)//true // console.log(NAN === NAN)//error // object. is can distinguish +0 from -0, Log (object.is (+0,-0))//false console.log(object.is (NAN, NAN))//trueCopy the code

16. Proxy

Before Vue3.0, you used Object.defineProperty to add read and write to attributes

Const person = {name:' LCJ ', age:18} const personProxy = new Proxy(person,{// create Proxy object for person, // Console. log(target,property)//{name: 'LCJ ', age: 18 } name return property in target? Target [property]:'default'// as the result of the external access attribute}, set(target,property,value){// Proxy target object, the name we want to write, If (property==='age'){// If (! Number.isInteger(value)){ throw new TypeError(`${value} is not int`) } } target[property] = value } }) console.log(personProxy.name)//100 //lcj console.log(personProxy.hobby)//default personProxy.gender = true console.log(personProxy)//{ name: 'lcj', age: 18, gender: true }Copy the code

17. The Proxy and defineProperty

  • DefineProperty can only monitor reads and writes of objects, Proxy is more powerful! (Omitted as in Example 16)
Const personProxy = new Proxy(person,{// omit... // Proxy target object, Delete property(target,property){console.log('delete ',property) delete target[property]}}) console.log(personProxy.name)//lcj personProxy.gender = true console.log(personProxy)//{ name: 'lcj', age: 18, gender: true } delete personProxy.age console.log(personProxy)//{ name: 'lcj', gender: true}Copy the code

  • Proxy better supports array object listening, overrides the array operation method. Idea: Hijack the method call process by overwriting the push, pop, and other methods on the array prototype with custom methods.

Let’s use the Proxy object to monitor the array

const list = [] const listProxy = new Proxy(list,{ set(target,property,value){ console.log('set',property,value)// Target [property] = value return true}}) // ListProxy.push (100)//set 0 Listproxy.push (200)//set 1 200Copy the code
  • Proxy oversees object reads and writes in a non-intrusive manner

The following figure shows the defineProperty method: proxy method is more reasonable, proxy method is like the above example

18. Reflect

Reflect is a static class, and you can’t build an instance object with new Reflect(). You can only call methods in this static class, such as reflect.get (), just like the Math object in JS. Reflect internally encapsulates a series of low-level operations on objects. The Reflect member method is the default implementation of the internal proxy method for handling objects.

const obj ={
  foo:'123',
  bar:'456'
}
const proxy = new Proxy(obj,{
  get(target,property){
    console.log('watch ')//watch
    return Reflect.get(target,property)
  }
})
console.log(proxy.foo)//123
Copy the code

A unified set of apis for manipulating objects is provided

const obj = {
  name:'lcj',
  age:18,
  sex:'woman'
}
// console.log('name' in obj)//true
// console.log(delete obj['age'])//true
// console.log(Object.keys(obj))//[ 'name', 'sex' ]

console.log(Reflect.has(obj,'name'))//true
console.log(Reflect.deleteProperty(obj,'age'))//true
console.log(Reflect.ownKeys(obj))//[ 'name', 'sex' ]
Copy the code



Related links:MDN(Reflect)

19. Promise

A better asynchronous programming solution solves the problem that traditional asynchronous programming callbacks are too deeply nested by using chain calls

20. Class class

Es6 used to define classes by defining functions and their prototype objects. To define a Person type, first define the Person function as the constructor of this type. In the constructor, access the instance object through this

function Person(name) { //
    this.name = name
}
Person.prototype.say = function () {
    console.log(`hi,my name is ${this.name}`)
}
let me = new Person('lcj')
me.say() //hi,my name is lcj
Copy the code

Es6 uses the class keyword to declare a type

Class Person {constructor(name) {this.name = name} say() {console.log(' hi,my name is ${this.name} ')}} let me = new Person('lcj') me.say()//hi,my name is lcjCopy the code

21. Static methods

Methods within a type are classified as instance methods and static methods. Instance methods need the instance object constructed by the type to be called, and static methods call each other through the type itself. Before we implemented static methods, we mounted methods directly on constructor objects (functions are also objects in JS and can mount properties and methods). Added the static keyword for adding static members in ES6.

Class Person {constructor(name) {this.name = name} say() {console.log(' hi,my name is ${this.name} ')} static create(name) { return new Person(name) } } let me = new Person('lcj') me.say()//hi,my name is lcj const tom = Person.create(' Tom ') // Create is a static method tom.say()//hi,my name is TomCopy the code

22. Class inheritance

Extends implements inheritance. Super always points to the parent class, and calling it calls the constructor of the parent class

class Student extends Person {
    constructor(name, id) {
        super(name)
        this.id = id
    }
    hello() {
        super.say()
        console.log(`my schoolId is ${this.id}`)//my schoolId is 100
    }
}
const s = new Student('xiaoming', '100')
s.say()//hi,my name is xiaoming
s.hello()//hi,my name is xiaoming
Copy the code

23. Set

A Set data structure, similar to an array, can be understood as a Set, but its internal members cannot be repeated

Add (1).add(2).add(3).add(4).add(2) console.log(s)//Set {1, 2, 3, console.log(s)//Set {1, 2, 3, console.log(s) ForEach (I => console.log(I))// 1 2 3 4 // for.. Of (es6) for (let I of s) {console.log(I)// 1 2 3 4} console.log(s.size)//4 // Check whether there is a value, Return true if so otherwise false console.log(s.haas (100))//false // determine if a value was deleted, Log (s.delte (3))//true console.log(s)//Set {1, 2, 4} // clear() console.log(s)//Set {} To heavy const array arr = [1, 2, 3, 1, 4, 3, 4, 5] const res = new Set (arr) console. The log (res) / / Set {1, 2, 3, 4, Const res2 = array. from(new Set(arr)) console.log(res2)//[1, 2, 3, 4, 5] //... Const res3 = [...new Set(arr)] console.log(res3)//[1, 2, 3, 4, 5]Copy the code

24. Map

Map data structures, similar to objects, are essentially collections of key-value pairs. The key name in the object structure must be a string.

const obj = {}
obj[true] = 'val1'
obj[123] = 'val2'
obj[{ a: 1 }] = 'val3'
console.log(obj)//{ '123': 'val2', true: 'val1', '[object Object]': 'val3' }

console.log(obj[{}])//val3
console.log(obj['[object Object]'])//val3
Copy the code

The key we set is not a string, but the print shows that it has been converted to a string (toString()) as a key. And you can see different key names and print the same result, which doesn’t make sense. A Map is a strict set of key-value pairs that Map the correspondence between two arbitrary data sets.

Const m = new Map() const Tom = {name: 'Tom'} 'Tom'} => 90} console.log(m.trap (Tom))//90 // check whether console.log(m.trap (Tom)) exists //true //forEach traverses (key value, Log (value, key) => {console.log(value, key)//90 {name: 'Tom'}}) // Delete console.log(m.delelete (Tom))//true console.log(m)//Map {} // Clear all keys console.log(m.clear)//[Function: clear] console.log(m)//Map {}Copy the code

The biggest difference from objects: Can use any type of value as the key name, while objects can only use string as the key name

25. Symbol

A whole new type of raw data

const cache = {}
//----- a.js ----
cache['foo'] = Math.random()
//----- b.js ----
cache['foo'] = 123
console.log(cache)
Copy the code

Cache [‘foo’]; cache[‘b_foo’]; cache[‘b_foo’]; cache[‘b_foo’]; This is a temporary circumvention of the problem, not a solution. We can solve this by using Symbol, which represents a unique value.

The const s = Symbol() //Symbol() function creates the Symbol type console.log(s)//Symbol() //Symbol is the original data type console.log(typeof s)//Symbol Console. log(Symbol() === Symbol())//false // Can accept an argument to determine which Symbol is used to distinguish console.log(Symbol('foo'))//Symbol(foo) console.log(Symbol('foo2'))//Symbol(foo2) console.log(Symbol('foo3'))//Symbol(foo3)Copy the code
Const obj = {} obj[symbol ()] = '123' obj[symbol ()] = 'ABC' console.log(obj)//{[symbol ()]: const obj[symbol ()] = 'ABC' console.log(obj)//{[symbol ()]: '123', [Symbol()]: 'abc' } const obj2 = { [Symbol()]: '123' } console.log(obj2)//{ [Symbol()]: '123' }Copy the code

Because a new Symbol is generated each time, duplicate keys are avoided

// a.js
const name = Symbol()
const person = {
    [name]: 'lcj',
    say() {
        console.log(this[name])
    }
}
// b.js
person.say()//lcj
Copy the code

Main function: add unique attribute names to objects. There are 7 data types as of ES2019, and BigIn type will store longer numbers in the future.

26. The Symbol

console.log(Symbol() === Symbol())//false
Copy the code

Because every time a Symbol is generated, it is a new Symbol, so how to reuse?

const s1 = Symbol.for('foo')
const s2 = Symbol.for('foo')
console.log(s1 === s2)//true
Copy the code

Symbol. For, Symbol maintains a global registry that provides a one-to-one correspondence between a string and a Symbol value. Instead of passing a string, symbols are converted to a string

console.log(Symbol.for('true') === Symbol.for(true))//true
Copy the code

The Symbol type provides a number of built-in Symbol constants that are used to identify internal methods. These identifiers allow custom objects to implement some of the built-in JS interfaces

console.log(Symbol.iterator)//Symbol(Symbol.iterator)
console.log(Symbol.hasInstance)//Symbol(Symbol.hasInstance)
Copy the code
Const obj = {} console.log(obj.tostring ())//[object object] const obj1 = {// Avoid duplicates with internal members [symbol.tostringTag]: 'XObject'} console.log(obj1.toString()) //[object XObject]Copy the code

Symbol is the name of the object property, which is particularly suitable as a private property of the object. It cannot be accessed by normal access, but can only be accessed by string attribute names

const obj2 = {
    [Symbol()]: 'symbol value',
    foo: 'normal value'
}
for (let key in obj2) {
    console.log(key)//foo
}
console.log(Object.keys(obj2))//[ 'foo' ]
console.log(JSON.stringify(obj2))//{"foo":"normal value"}
Copy the code

Gets the Symbol() attribute name

console.log(Object.getOwnPropertySymbols(obj2))//[ Symbol() ]
Copy the code

Keys gets the string type property name, getOwnPropertySymbols gets the Symbol type property name

27. for… Of circulation

For is suitable for traversing ordinary arrays, for.. In is good for traversing key/value pairs, and there are some object traversal methods, such as forEach, for… Of serves as a unified way to traverse all data structures

const arr = [100, 200, 300, 400]
for (const i of arr) {
    console.log(i)//100 200 300 400
}
arr.forEach(i => {
    console.log(i)//100 200 300 400
})
Copy the code

for... Of can terminate the loop at any time,forEach cannot terminate the loop,some returns true to terminate the loop, and every returns false to terminate the loop

for (const item of arr) { console.log(item)//100 200 if (item > 100) { break; // arr.foreach ()// cannot terminate traversal // arr.some()// returns true to terminate // arr.every()// returns false to terminateCopy the code

Traversal returns -set returns the value

const s = new Set(['foo', 'bar'])
for (const i of s) {
    console.log(i)//foo bar
}
Copy the code

Traversal return -map Return key value pair, const [key, value] of m disassembly

const m = new Map() m.set('foo', '123') m.set('bar', '345') for (const i of m) { console.log(i)//[ 'foo', '123'] ['bar', '345']} for (const [key, value] of m) {console.log(key, value)//foo 123; bar 345 }Copy the code

[28 iterable interface] [28 iterable interface] [28 iterable interface]

} for (const item of obj) {//Error: obj is not iterable console.log(item)}Copy the code

28. Iterable interface

The above saidfor... Unified traversal of dataMore and more structured data types can be represented in ES. In order to provide a unified traversal mode for various data types,Es6 provides the Iterable interfaceThe Iterable interface is for… Of the premise

Look at the array prototype object __proto__, which has aSymbol(Symbol.iterator)Three methods can be used for… The name of this method is iterator. Iterator convention We must mount iterator methods on our objects.

Conclusion: Therefore, it can be directly blamed for… Of traversing the data needs to implement the iterator interface, its internal must mount the iterator method, this method needs to return a method with the next object, constantly call next return data

Const set = new set (['foo', 'bar', 'baz']) const iterator = set[symbol.iterator]() Next ())//{value: 'foo', done: false} console.log(iterator.next())//{value: 'bar', done: false } console.log(iterator.next())//{ value: 'baz', done: false } console.log(iterator.next())//{ value: undefined, done: true } console.log(iterator.next())//{ value: undefined, done: true }Copy the code

29. Implement iterable interfaces

Basic implementation

Const obj = {// implement an iterable interface with [symbol.iterator] [symbol.iterator]: function () {return {// implement an iterator for next next: Function () {return {value:' LCJ ', done:true}}}}} for (const I of obj) {console.log(I)// Loop body not executed because done:true}Copy the code

A modified

Const obj = {// implement an iterable interface with [symbol. iterator] store: ['foo', 'bar', 'baz'], // create an array [symbol. iterator]: Function () {let index = 0 const self = this; function () { const result = { value: self.store[index], done: index >= self.store.length } index++ return result } } } } for (const i of obj) { console.log(i)//foo bar baz }Copy the code

30. Iterator pattern

Const todos = {life: [' eat ', 'sleep '], learn: } for (const I of todos.life) {console.log(I)// eat/sleep}Copy the code

Todos. life todos.learn is highly coupled,todos changes, use changes. Solution:

Const todos = {life: [' dinner 'and' sleep '], learn: [' language ', 'English'], each: function (callback) { const all = [].concat(this.life, This. Learn) for (const item of all) {callback(item)}} todos.each(item => console.log(item))//Copy the code

Implement iterable interfaces

Const todos = {life: [' dinner 'and' sleep '], learn: [' language ', 'English'], each: function (callback) { const all = [].concat(this.life, this.learn) for (const item of all) { callback(item) } }, [symbol.iterator]: function () {const all = [...this.life,...this.learn] let index = 0 return {next: function () { return { value: all[index], done: Index++ >= all.length}}}}} for (const I of todos) {console.log(I)////Copy the code

31. Generator -Generator

Avoid deep nested callbacks in asynchronous programming and provide better asynchronous programming solutions.

function* foo() { console.log('lcj') return 100 } const result = foo() console.log(result)//Object [Generator] {}, there is also a next method console.log(result.next())// LCJ; { value: 100, done: Function * foo1() {console.log('111') yield 100 console.log('222') yield 200 console.log('333') yield 300 } const generator = foo1() console.log(generator.next())//111 { value: 100, done: false } console.log(generator.next())//222 { value: 200, done: false } console.log(generator.next())//333 { value: 300, done: false } console.log(generator.next())//{ value: undefined, done: true }Copy the code

The generator function will automatically return a generator object for us, call next of that function, and the function will start executing. The yield keyword will be paused during execution, and any value after yield will be returned as the result of next. Until execution is complete.

32. Generator applications

  • Give the device
function* createIdMaker() {
    let id = 1
    while (true) {
        yield id++
    }
}
const idMaker = createIdMaker()
console.log(idMaker.next().value)//1
console.log(idMaker.next().value)//2
console.log(idMaker.next().value)//3
console.log(idMaker.next().value)//4
Copy the code
  • Implement the iterator method using a Generator function

The original writing

Const todos = {life: [' dinner 'and' sleep '], learn: [' language ', 'English'], [Symbol. The iterator] : function () { const all = [...this.life, ...this.learn] let index = 0 return { next: function () { return { value: all[index], done: index++ >= all.length } } } } }Copy the code

After the change

Const todos = {life: [' dinner 'and' sleep '], learn: [' language ', 'English'], [Symbol. The iterator] : function* () { const all = [...this.life, This. Learn] for (const item of all) {yield item}} for (const I of todos) {console.log(I)}Copy the code

Overview of ES2016

Compared with ES2015, there are only two more

  • 1. Array instance object includes method (array.prototype. includes)NaN cannot be found using indexOf,includes can be found, return true
Const arr = ['foo', 1, NaN, false] Cannot find NAN console.log(arr.indexof ('foo')) console.log(arr.indexof (NAN)) console.log(arr.includes('foo')) console.log(arr.includes(NaN))Copy the code
  • 2. The index operator **
console.log(Math.pow(2, 10))//1024
console.log(2 ** 10)//1024
Copy the code

Overview of ES2017

  • 1. Three extension methods for Object

    • Object.values
      console.log(Object.values(obj)) //[ 'value1', 'value2' ]
    Copy the code

    Values (obj) returns an array of all values, and object.keys (obj) returns an array of all keys

    • Object.entries
    Console. log(object.entries (obj))//[['foo', 'value1'], ['bar', 'value2']] for (const [key, value] of Object.entries(obj)) { console.log(key, value) //foo value1; Log (new map (object.entries (obj))) // map {'foo' => 'value1', 'bar' => 'value2'}Copy the code
    • Object.getOwnPropertyDescriptors
    Const p1 = {firstName: 'cj', lastName: 'l', get fullName() { return this.firstName + ' ' + this.lastName } } console.log(p1.fullName)//cj l const p2 = Object.assign({}, p1) p2.firstName = 'abc' console.log(p2)//{ firstName: 'abc', lastName: 'l', fullName: 'cj l'} // The fullName is copied as a normal attributeCopy the code

    To solve

      const p1 = {
          firstName: 'cj',
          lastName: 'l',
          get fullName() {
              return this.firstName + ' ' + this.lastName
          }
      }
      const des = Object.getOwnPropertyDescriptors(p1)
      console.log(des)
      // { firstName:
      //     { value: 'cj',
      //       writable: true,
      //       enumerable: true,
      //       configurable: true },
      //    lastName:
      //     { value: 'l',
      //       writable: true,
      //       enumerable: true,
      //       configurable: true },
      //    fullName:
      //     { get: [Function: get fullName],
      //       set: undefined,
      //       enumerable: true,
      //       configurable: true } }
      const p2 = Object.defineProperties({}, des)
      p2.firstName = 'abc'
      console.log(p2.fullName)//abc l
    Copy the code
  • 2. The string padStart/padEnd (string. Prototype. PadStart/string. The prototype. PadEnd)

const books = {
    html: 5,
    css: 16,
    js: 128
}
for (const [name, count] of Object.entries(books)) {
    console.log(`${name.padEnd(16, '-')}|${count.toString().padStart(3, '0')}`)
}
// html------------|005
// css-------------|016
// js--------------|128
Copy the code
  • 3. Add trailing commas to function arguments to allow code management tools to find code changes more accurately
function foo(bar, baz, ) { }
const arr = [100, 200, 300,]
Copy the code
  • 4.Async/Await completely solves the Async programming callback hell problem, essentially promises candy