ES6~ES12 knowledge combing and summary

1. let and const

The appearance of these two always seems to appear for the development of code specifications. We want components to give up var and use let and const more in the project.

The difference with var:

  • var has variable promotion and initialization promotion, the value can be changed, var only has function scope
  • let has variable promotion, no initial value promotion, and the value can be changed
  • const has variable promotion, no initialization promotion, and the value is immutable. But if it is a definition object, the attributes are variable

Explanation of the temporary dead zone problem: In fact, let and const have variable promotion, but there is no initialization promotion:

var name='Amelian'
function fn(){
    console.log(name);
    let name = 'hzz'
}
fn()// Cannot access 'name' before initialization

2. Default parameters

        You have encountered such a problem in development, if the parameters are not passed, you can set the default parameters

function(name,age){
    var name=name || 'Amelian';
    var age=age || 18;
    console.log(name,age);
}
fn()// 林三心 18

        But it is really not elegant to write this way, you can use the default parameters of ES6

function fn(name='Amelian',age=18){
    console.log(name,age)
}

fn()// 林三心 18
fn('sunshine', 22) // sunshine 22

3. Spread operator

Before es6, if you want to concatenate multiple arrays, you generally use the following operations:

const arr1=[1,2,4]
const arr2=[1,5,4]
const arr3=[1,8,4]

const arr=arr1.concat(arr2).concat(arr3)

With es6, you can directly use the spread operator to operate

const arr1=[1,2,4]
const arr2=[1,5,4]
const arr3=[1,8,4]

const arr=[...arr1,...arr2,...arr3]

4. Remaining parameters

You may encounter this kind of problem. For a function, the number of incoming parameters is uncertain, so you can use the remaining parameters of es6

function fn(name,...params){
    console.log(name);
    console.log(params)
}

fn('Amelian',1,2) // Amelian [ 1, 2 ]
fn('Amelian',1,2,3,4,5) // Amelian [ 1, 2, 3, 4, 5 ]

5. Template string

Previously, the only way to do this was with strings:

const name='Amelian'
const age=22

console.log(name+'今年'+age+'岁啦')// // Amelian今年22岁啦

Now it is possible to do this, it will be more elegant

const name='Amelian'
const age=22

console.log(`${name}今年${age}岁啦`)// // Amelian今年22岁啦

6.Object.keys

It can be used to obtain the set of keys to which the object belongs, and then to obtain the vakue corresponding to the key

const obj={
    name:'Amelain',
    age:18,
    gender:'女'

}

const keys=Object.keys(obj)
console.log(keys)//['name','age','gender']

7. Arrow functions

Before es6, ordinary functions were used

function fn(){}
const fn=function(){}

es6 newly added arrow function

The difference between arrow functions and ordinary functions:

  • Arrow functions cannot be used as constructors, and new cannot be used
  • Arrow functions do not have their own this
  • Arrow functions have no arguments object
  • Arrow functions have no prototype object

8. Array.prototype.foreach (array traversal method)

const eachArr=[1,2,3,4,5]
//三个参数:遍历项、索引、数组本身
//配合箭头函数
eachArr.forEach((item,index,arr)=>{

    console.log(item,index,arr)
})
1 0 [ 1, 2, 3, 4, 5 ]
2 1 [ 1, 2, 3, 4, 5 ]
3 2 [ 1, 2, 3, 4, 5 ]
4 3 [ 1, 2, 3, 4, 5 ]
5 4 [ 1, 2, 3, 4, 5 ]

9. Array.prototype.map (loop through, return a new array)

Commonly used to return a new processed array

const mapArr=[1,2,3,4,5]

//三个参数:遍历项、索引、数组本身
//配合箭头函数,对每个元素进行翻倍

const mapArr2=mapArr.map((num,index,arr)=>{
    return 2*num
})
console.log(mapArr2)

[ 2, 4, 6, 8, 10 ]

10、Array.prototype.filter

As the name suggests, it is a method for filtering

const filterArr=[1,2,3,4,5,6]

//三个参数:遍历项、索引、数组本身
//配合箭头函数,返回大于3的集合

const filterArr2=filterArr.filter((item,index,arr)=>{
    return num>3
})

[4,5]

11、Array.prototype.some

some, meaning only one is true, then return true

const someArr=[false,true,true,false]

//三个参数:遍历项、索引、数组本身
//配合箭头函数,只要有一个是为true,就返回true,一个true都没有,就返回false

const someArr2=someArr.filter((bol,index,arr)=>{
    return bol
})

console.log(someArr2)//true

12、Array.prototype.every

every is the opposite of some, some means as long as there is one, and every means that all are true before returning true

const everyArr=[false,true,true,false]

//三个参数:遍历项、索引、数组本身
//配合箭头函数,只要有一个是为true,就返回true,一个true都没有,就返回false

const everyArr2=everyArr.filter((bol,index,arr)=>{
    return bol
})

console.log(everyArr2)//false

13、Array.prototypr.reduce

  • The first parameter callback function: pre is the value of the last return, and next is the value of the current traversal item of the array
  • The second parameter is the initial value, which is also the first pre

Give two examples:

//计算1+2+3+4+5
const reduceArr=[1,2,3,4,5]
const sum = reduceArr.reduce((pre,next)=>{
    return pre+sum
},0)
console.log(sum)//15


//统计元素出现的个数
    const nameArr = ['hzz', 'wd', 'lhk', 'lhk', 'hzz']
    const totalObj = nameArr.reduce((pre, next) => {
      //由于初始值为{}空对象,因此pre[next]表示obj.next,
      //由于此时{}为空,因此使用pre[]的方式来表示对象的属性
      if (pre[next]) {
        pre[next]++//执行次数加一
      } else {
        pre[next] = 1//表示再次遍历的时候没有重复出现了
      }
      return pre
    }, {})
    console.log(totalObj)//{hzz: 2, wd: 1, lhk: 2}

14. Abbreviation of the object attribute with the same name

        Before, the attribute with the same name needs to be written like this

const name = 'Amelian';
const age =22;

const obj={
    name:name,
    age:age
}

cosole.log(obj)//{name:'Amelian',age:22}

For the new syntax of es6, now only need to write like this

const name = 'Amelian';
const age =22;

//属性同名可简写
const obj={
    name
    age
}

cosole.log(obj)//{name:'Amelian',age:22}

15、Promise

        Promises are a solution to asynchronous programming that are more logical and powerful than traditional solutions - callback functions and events. It was first proposed and implemented by the community.

        The so-called promise is simply a container that holds the result of something that will end in the future (usually an asynchronous operation). Syntactically, a Promise is an object from which messages for asynchronous operations can be obtained. Promise provides a unified API, and various asynchronous operations can be processed in the same way.

        Promise objects have the following characteristics

  1. The state of the object is not affected by the outside world. The Promise object represents an asynchronous operation and has three states: pedding (in progress), fulfilled (successful), and rejected (failed). Only the result of an asynchronous operation can determine which state it is currently in, and no other operation can change this state.
  2. Once the state changes, it will not change again, and this result can be obtained at any time. There are only two possibilities for the state change of the Promise object: fulfilled from pending programming and rejected from pending programming . As long as the two situations happen, the state will freeze and will not change again, and this result will be maintained consistently. This is called resolved

Note: For the convenience of writing, the following resolved only refers to the fulfilled state and does not include the rejected state.

With the Promise object, asynchronous operations can be expressed as synchronous operations, avoiding nested callback functions. In addition, the Promise object provides a unified interface, making it easier to control asynchrony.

15.1 Basic Usage

ES6 stipulates that the Promise object is a constructor used to produce Promise instances.

The following code creates a Promise instance

    const promise = new Promise(function (resolve, reject) {
      //...some code
      if (/*异步操作成功*/) {
        resolve(value)
      }else{
        reject(error)
      }
    })

The Promise constructor receives a function as a parameter. The two parameters of the function are resolve and reject . They are two functions provided by the javaScript engine and do not need to be deployed by yourself.

        When the programming of the Promise object fails, that is, when the asynchronous operation fails, it is called, and the error reported by the asynchronous operation is passed as a parameter.

        The Promise instance is generated, and the then method can be used to formulate the callback functions of the resolved state and the rejected state respectively.

    promise.then(function (value) {
      //success
    }, function (error) {
      //failure
    })

The then method can accept two callback functions as parameters. The first callback function is called when the state programming of the Promise object is resolved, and the second callback function is called when the Promise object becomes rejected. Both functions are optional. It is not necessary to provide, they all accept the value passed from the Promise object as a parameter.

Below is a simple example of a Promise object.

    function timeout(ms) {
      return new Promise((resolve, reject) => {
        setTimeout(resolve, ms, 'done')
      })
    }

    timeout(100).then((value) => {
      console.log(value)
    })

In the above code, the timeout method will return a Promise instance, indicating that the result will occur after a period of time. After the specified time (ms parameter), the state of the Promise instance becomes resolved, and the callback function bound by the then method will be triggered.

Promise will be executed immediately after new creation

    let promise = new Promise(function (resolve, reject) {
      console.log('Promise');
      resolve();
    })
    promise.then(function () {
      console.log('resolved')
    })
    console.log('hi')

 In the above code, Promise is executed immediately after it is created, so the first output is Promise

, and then, the callback function specified by the then method will not be executed until all synchronization tasks in the current script are executed, so resolved is output at the end.

The following is an example of an Ajax operation implemented with a Promise object:

const getJSON = function(url) {
  const promise = new Promise(function(resolve, reject){
    const handler = function() {
      if (this.readyState !== 4) {
        return;
      }
      if (this.status === 200) {
        resolve(this.response);
      } else {
        reject(new Error(this.statusText));
      }
    };
    const client = new XMLHttpRequest();
    client.open("GET", url);
    client.onreadystatechange = handler;
    client.responseType = "json";
    client.setRequestHeader("Accept", "application/json");
    client.send();

  });

  return promise;
};

getJSON("/posts.json").then(function(json) {
  console.log('Contents: ' + json);
}, function(error) {
  console.error('出错了', error);
});

 In the above code, getJSON is an encapsulation of the XMLHttpRequest object, which is used to issue an HTTP request for json data and return a Promise object. It should be noted that inside getJSON, the resolve and reject functions both carry parameters.

If both the resolve function and the reject function are called with parameters, their parameters will be passed to the callback function (that is, the function executed in then). The parameter of the reject function is usually an instance of the Error object, indicating the error thrown; the parameter of the resolve function may be an exception Promise object in addition to the normal value, such as the following:

    const p1 = new Promise((resolve, reject) => {
      //....
    })
    const p2 = new Promise((resolve, reject) => {
      //....
      resolve(p1)
    })

In the above code, both p1 and p2 are promise instances, but the resolve method of p2 takes p1 as a parameter, that is, the result of one asynchronous operation returns another asynchronous operation. In other words, the state of p1 determines the state of p2. If the state of p1 is pending, then the callback function of p2 will wait for the state of p1 to change. If the state of p1 is resolved or rejected, then the callback function of p2 will be Do it now.

    const p1 = new Promise((resolve, reject) => {
      setTimeout(() => {
        reject(new Error('fail'), 3000)
      })
    })
    const p2 = new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve(p1, 1000)
      })
    })
    p2.then(result => console.log(result)).catch(error => console.log(error))

Note that this is the state of p1 will be passed to p2,

Generally speaking, after calling resolve or reject, the mission of Promise is completed, and subsequent operations should be placed in the then method. It should not be written directly after resolveor reject, so add a return statement in front of them at the end, so that there will be no surprises.

new Promise((resolve, reject) => {
  return resolve(1);
  // 后面的语句不会执行
  console.log(2);
})

15.2、Promise.prototype.then()

        The Promise instance has a then method, that is, the then method is defined on the prototype object Promise.prototypr, and its function is to add a callback function when the state changes to the Promise instance. As mentioned earlier, the first parameter of the then method is the callback function of the resolved state, and the second parameter is the callback function of the rejected state, both of which are optional.

The then method returns a new Promise instance (not the original Promise instance), so you can use chain writing to call another then method after the then method.

15.3 、Promise.prototype.catch()

Used to specify a callback function when an error occurs.

    getJSON('/posts.json').then(function (posts) {
      //....
    }).catch(function (error) {
      //处理getJSON和前一个回调函数运行时发生的错误
      console.log('发生错误!', error);
    })

In the above code, the getJSON() method returns a Promise object. If the object status is resolved, the callback function specified by the then() method will be called; if the asynchronous operation throws an error, the status will become rejected, and the catch will be called () method specifies the callback function. Handle this error. In addition, if the callback function specified by the then() method throws an error during operation, it will also be caught by the catch() method.

        Generally speaking, do not define the callback function of the reject state in the then() method, that is, the second parameter of then, always use the catch method

// bad
promise
  .then(function(data) {
    // success
  }, function(err) {
    // error
  });

// good
promise
  .then(function(data) { //cb
    // success
  })
  .catch(function(err) {
    // error
  });

In the above code, the second way of writing is better than the first way of writing, because the second way of writing can catch errors in the execution of the previous then method, and it is also closer to the synchronous way of writing (try/catch). Therefore, it is recommended to always use catch() method without using the second parameter of the then() method.

16、class

In the past, we used the reach function to generate objects, doing

    function Person(name, age) {
      this.name = name;
      this.age = age
    }
    Person.prototype.sayName = function () {
      console.log(this.name)
    }
    const person1 = new Person('hzz', 18)
    console.log(person1)
    person1.sayName()

 tip: The essence of class is also function , and class is the grammatical sugar of function

Now with es6, it is possible to do

    class Person {
      constructor(name) {
        this.name = name;
      }
      sayName() {
        console.log(this.name)
      }
    }

    //由于class的本质也是函数,因此通过class创建对象的时候也是通过new的方式
    const person1 = new Person('hzz');
    person1.sayName()//'hzz'

        In addition to the above, you also need to know the above knowledge points of the class

        Static properties and static methods, properties and methods defined using static can only be used by the class itself, and instances created through the class cannot be used

    class Person {
      constructor(name) {
        this.name = name;
      }
      static age = 22
      static fn() {
        console.log('哈哈')
      }
      sayName() {
        console.log(this.name)
      }
    }

    console.log(Person.age);//22
    Person.fn()//哈哈

    const person1 = new Person('hzz');
    person1.sayName()//'hzz'
    person1.fn()//undefined
    console.log(person1.age)//fn is not a function

extend inheritance

    class Animal {
      constructor(name, age) {
        this.name = name;
        this.age = age;
      }
    }

    class Cat extends Animal {
      say() {
        console.log(this.name, this.age);
      }
    }

    const cat1 = new Cat('ketty', 3)// 继承了Animal的构造器
    cat1.say()// ketty 3

17. Structural assignment

In the past, if you want to extract the properties in the object, you need to do this

    const obj = {
      name: 'Amelain',
      age: 22,
      gender: '女'
    }

    const name = obj.name;
    const age = obj.age;
    const gender = obj.gender;
    console.log(name, age, gender)//Amelian 22 女

ES6 adds syntax for structure assignment

  • The first property is the property name in the object you need to structure assignment
  • The second attribute is the name of the attribute you want to assign. If you want to be consistent with the original, you can omit it, otherwise you can redefine it
  • The same is true for nested assignments,
    const obj = {
      name: 'Amelain',
      age: 22,
      gender: '女',
      doing: {
        morning: '摸鱼',
        afternoon: '摸鱼',
        evening: 'sleep'
      }
    }
    const { name, age, gender } = obj
    console.log(name, age, gender)//Amelian 22 女

    //结构重命名
    const { name: myname } = obj
    console.log(myname)

    //嵌套结构
    const { doing: { evening } } = obj;
    console.log(evening);//sleep

18. find and findIndex

  • find: used to find the first qualified array member, its parameter is a callback function, each array member will execute this callback function , if not found, return undefined
  • findIndex: Used to find the index of the first array member that meets the criteria, if not found, return -1
    //这里传递的是一个回调函数,然后findArr数组中的元素都会以此执行这个回调函数
    const arr = [1, 2, 5, 6, 9, 8, 21, 15]
    const res1 = arr.find((value, index, arr) => {
      return value === 9
    })
    console.log(res1)//9 返回被查找的元素
    const res2 = arr.findIndex((value, index, arr) => {
      return value === 9
    })
    console.log(res2)//4 返回所查找元素的索引

19、for in 和 for of

  • for in : traversal method, which can traverse arrays and objects
  • for of : traversal method, only arrays can be traversed, non-iterable objects cannot be traversed

First look at for in:

    const obj = { name: 'Amelain', age: 22, gender: '女' }
    const arr = [1, 2, 3, 45, 6]
    for (let key in obj) {
      console.log(key + '----->' + obj[key])
    }
    /*
    name----->Amelain
    age----->22
    gender----->女
    */

    for (let index in arr) {
      console.log(index + '----->' + arr[index])
    }

    /*
    0----->1
    1----->2
    2----->3
    3----->45
    4----->6
    */

Look at for of:

    for (let item of arr) {
      console.log(item)//逐个输出数组全部元素
    }

Summary: for in can traverse objects and arrays at the same time, and the direct elements obtained by the traversal are the properties of the object or the index of the array; for of traverses the array, and the obtained elements are directly the elements of the array, and the objects cannot be traversed.

20. set and map

20.1 First talk about the usage of set

    //可不传数组
    const set1 = new Set()
    set1.add(1);
    set1.add(2);
    console.log(set1)//Set(2) {1, 2}

    //也可以传递数组
    const set2 = new Set([1, 2, 3])

    //添加元素使用 add
    set2.add(4);
    set2.add('Amelian')
    console.log(set2)//Set(5) {1, 2, 3, 4, 'Amelian'}

    //检查是否含有某个元素 使用has
    console.log(set2.has(2))//true

    //查看长度
    console.log(set2.size)//5

    //删除元素 使用delete
    set2.delete(2)
    console.log(set2)//Set(4) {1, 3, 4, 'Amelian'}

Let's talk about the non-repeatability of set

    // 增加一个已有的元素,则增加无效,会被自动去重
    const set1 = new Set([1])
    set1.add(1)
    console.log(set1)//Set(1) {1}

    //传入的数组中有重复项,会自动去重
    const set2 = new Set([1, 2, 1, 3, 3, 'Amelian'])
    console.log(set2)//Set(4) {1, 2, 3, 'Amelian'}

In the non-repeatability of Set , pay attention to the reference data type and NaN


    //两个对象都是不同指针,所以没法去重
    const set1 = new Set([1, { name: 'Amelian' }, 2, { name: 'Amelian' }])
    console.log(set1)//Set(4) {1, { name: 'Amelian' }, 2, { name: 'Amelian' }}

    //两个对象是同样一个指针,则能去重
    const obj = { name: 'Amelian' }
    const set2 = new Set([1, obj, 2, obj])
    console.log(set2) Set(3) { 1, { name: 'Amelian' }, 2 }

    //我们知道NaN!=NaN,即NaN是自身不等于自身的,但是在Set中还是会被去重掉
    const set = new Set([1, NaN, 1, NaN])
    console.log(set)//Set(2) {1, NaN}

Using the non-repetitive nature of set, you can realize deduplication of arrays

    const arr = [1, 2, 14, 7, 8, 9, 2, 1, 7, 9]
    //Set可利用扩展运算符转为数组
    //下面的操作即是先把这个需要去重的数组作为参数传给Set,Set的不重复性会将数组去重
    //去重后已经变为Set对象了,因此需要重新将Set转成数组

    const changeArr = [...new Set(arr)]

    //与上面的操作等价
    const set1 = new Set(arr)
    const quchongArr = [...set1]
    console.log(quchongArr)

20.2 Map

       The biggest advantage of Map over object is that the key is not limited by type

    const map1 = new Map()
    //新增键值对 使用set(key,value)
    map1.set(true, 1);
    map1.set(1, 2);
    map1.set('哈哈', 'xixi')
    console.log(map1)//Map(3) {true => 1, 1 => 2, '哈哈' => 'xixi'}

    //判断map中是否含有某个key,使用has(key)
    console.log(map1.has('哈哈'))//true

    //获取map中某个键值对,使用get(key)
    console.log(map1.get(true))//1

    //删除map中某个键值对 使用delete(key)
    map1.delete('哈哈')
    console.log(map1)//Map(2) {true => 1, 1 => 2}


    //定义map,也可以传入键值对数组集合
    const map2 = new Map([[true, 1], [1, 2], ['哈哈', 'xixi']])
    console.log(map2)//Map(3) {true => 1, 1 => 2, '哈哈' => 'xixi'}

 ES7

21、includes

Pass in the element, if the element can be found in the array, return true, otherwise return false

    const includeArr = [1, 2, 3, 'Amelian', 'Cifum']
    const isAn = includeArr.includes('Amelian')
    console.log(isAn)//true

22. Exponentiation operator

Before exponentiation, we need to write

const num = Math.pow(3,2) //9

ES7 provides the exponentiation operator: **

const num = 3**2 //9

******************************************************************************************************* *****


23、Object.values(obj)

A collection of values ​​that can be used to get objects

    const obj = {
      name: 'Amelian',
      age: 22,
      gender: '女'
    }

    const values = Object.values(obj)
    console.log(values)//['Amelian', 22, '女']

24、Object.entries

A collection of key-value pairs that can be used to get an object

    const obj = {
      name: 'Amelian',
      age: 22,
      gender: '女'
    }

    const entries = Object.entries(obj)
    console.log(entries)

 25、async/await

 This is a very common syntax. My understanding is: perform asynchronous operations in a synchronous manner.

We may encounter this kind of scenario at ordinary times. Interface 1 requests data 1, and data 1 is used as a parameter of request 2 to request data 2. We will use promise as follows:

    function fn() {
      //模拟第一次请求
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          resolve(5)
        }, 1000)
      }).then(res => {
        //模拟第二次请求
        new Promise((resolve, reject) => {
          setTimeout(() => {
            //拿到第一次请求得到数据去*10,当做第二次请求的数据
            resolve(res * 10)
          }, 2000)
        }).then(res => {
          console.log(res)
        })
      })
    }
    fn()//1+2=3  3秒后输出50

Such nesting is unsightly. If there are many interfaces, then nest many layers back. At this time, we can use async/await to execute asynchronously in a synchronous manner. Note the following points:

  • await can only be used in async functions
  • It is best to connect Promise after await, if it is followed by a normal function, it will be executed directly
  • The async function returns a Promise
    function fn1() {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          resolve(5)
        }, 1000)
      })
    }

    function fn2(data) {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          resolve(data * 10)
        }, 2000)
      })
    }

    async function req() {
      //同步的方式执行异步,像排队一样
      const data1 = await fn1()//等待1秒后返回数据再往下继续执行
      const data2 = await fn2(data1)//拿到data1去请求 2秒后,往下走
      console.log(data2) //总共3秒后 输出50
    }
    req()


*************************** following ES9******************** *****


26、Promise.finally

Added Promise method, regardless of failure or success status, this function will be executed

    new Promise((resolve, reject) => {
      resolve('成功喽')
    }).then(
      res => {
        console.log(res),
          err => { console.log(err) }
      }
    ).finally(() => {
      console.log('我是finall')
    })


    new Promise((resolve, reject) => {
      reject('失败哩')
    }).then(
      res => {
        console.log(res),
          err => { console.log(err) }
      }
    ).finally(() => {
      console.log('我是finall')
    })

*************************** following ES9******************** *****


27、Array.flat

I have a two-dimensional array, and I want to convert it into a one-dimensional array:

    const arr = [1, 2, 3, [4, 5, 6]]
    console.log(arr.flat())//[1, 2, 3, 4, 5, 6]

    //还可以传递参数,参数为降维的次数
    const arr1 = [1, 2, 3, [4, 5, 6, [7, 8, 9]]]
    console.log(arr1.flat(2))//[1, 2, 3, 4, 5, 6, 7, 8, 9]


    //如果传入的参数是一个无限大的数字,那么就表示无论该数组是几维的,均被降维一维数组
    const arr2 = [1, 2, 3, [4, 5, 6, [7, 8, 9, [10, 11, 12]]]]
    console.log(arr2.flat(Infinity))//[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]

28、Array.flatMap

There is an existing demand:

let arr = ["科比 詹姆斯 安东尼", "利拉德 罗斯 麦科勒姆"];

 Convert the above array to

[ '科比', '詹姆斯', '安东尼', '利拉德', '罗斯', '麦科勒姆' ]

 first thought map + flat

    let arr = ["科比 詹姆斯 安东尼", "利拉德 罗斯 麦科勒姆"];
    const arr2 = arr.map((item) => {
      return item.split(" ")//即是将数组中每一项(字符串)每个空格处组成数组

    })
    console.log(arr2)
    //[ ['科比', '詹姆斯', '安东尼'] , ['利拉德', '罗斯', '麦科勒姆'] ]
    console.log(arr2.flat())//['科比', '詹姆斯', '安东尼', '利拉德', '罗斯', '麦科勒姆']

29, ?. and ?..

29.1   ?.

For example, we need a variable, which is an array and has a length, to do certain operations

    const list = null;
    //do somethoing
    if (list && list.length) {
      //do something
    }

    //使用可选链
    const list = null;
    if (list?.length) {
      //do something
    }

For example, if there is an object, we want to take a value that may not exist, and we are not even sure whether obj exists or not.

    const obj = {
      cat: {
        name: '哈哈'
      }
    }
    const dog = obj?.dog?.name//undefined

For example, if there is an array, I am not sure if it exists or not, if it exists, take the value with index 1

    const arr = null;
    const item = arr && arr[1]

    //使用可选链
    const arr = null;
    const item = arr?.[1]

For example, if there is a function, we are not sure whether it exists or not, if it exists, execute it

    const fn = null;
    //do something
    const res = fn && fn()

    //可选链
    const res = fn?.()

Guess you like

Origin blog.csdn.net/weixin_46872121/article/details/122831801