ES7-11
Senior JavaScript
Published: 2020-03-10

The article contains the knowledge of ES7-11…

ES7

Array.prototype.includes

以前使用indexOf来判断

指数运算符

ES8

async

注意async函数的返回值为promise对象,且promise对象的结果由async函数执行的返回值决定,如果返回结果不是一个Promise对象,他也是一个成功的Promsie,比方说我们直接写return;,那他就是一个resolved状态,value为undefined的Promise(反正就是跟直接用Promise一样)

由于是Promise,所以可以.then

await

注意async里面执行函数失败的情况下需要用try catch去捕获

另外,await 后面可以跟任何的JS 表达式。虽然说 await 可以等很多类型的东西,但是它最主要的意图是用来等待 Promise 对象的状态被 resolved。如果是被rejected那就要try catch去捕获了。

与axios连用

由于axios本身就返回一个Promise,所以可以直接写在await后面

Object.keys、Object.values和Object.entries

Object.entries返回键值对数组,主要可以方便创建map,如上图

Object.getOwnPropertDescriptors

我们发现每个属性里面的configurable、enumerable等跟Object.create()里面的第二个参数很像,跟Object.defineProperty()里面的有些参数也很像:

事实上,Object.getOwnPropertyDescriptors获取的就是对象的所有属性的这些描述值,所以被称为是获取对象属性的描述对象

用途

获取这些属性的描述对象能干嘛呢?

主要是能够深层次的拷贝对象,使得对象的属性的描述也能一起拷贝过来

ES9

在ES9中为对象提供了像数组一样的rest参数和扩展运算符

我们来试一下:

使用解构:

使用rest:

扩展运算符对对象的操作:

对对象用扩展运算符可以取出对象中的键值对

使用该特性可以将多个对象的键值对合并到一个新的对象里面,如上图

正则扩展

命名捕获分组

返回的是一个数组,下标0为原字符串,1为第一组,2为第二组,以此类推

但是我们可以看到上面的groups是undefined

命名捕获分组:

在小括号中用 ?<名称> 的方式命名该小括号的组,这个时候我们会发现上面的groups里面就有内容了,且key就是重命名的名称,value就是组获取到的内容。

如何通过groups获取组里面的内容呢:

零宽断言

正向

我们只想匹配555,不想匹配前面的数字,可以通过:/\d+啦/的方式,但是这样会把“啦”也匹配进来,我们不想让“啦”进来,就给“啦”加一个(?=)表示断言匹配的内容后面一定是“啦”这个字而且不会把“啦”匹配进来,如上图

反向

dotAll模式

我们知道正则里面的 . 代表除换行符以外的任意字符,现在我们想让他把换行符也算上。

原先我们匹配上图的a标签和p标签很麻烦还要考虑换行,也就是上图要加\s+的原因

现在在后面加上/s,就可以不用考虑换行的问题了

当然我们还可以加上 g,表示全局匹配,如上图

另外还有 i 表示忽略大小写

ES10

Object.fromEntries

用于二维数组创建对象:

用于map创建对象:

这里我们会想到Object.entries():

我们知道Object.entries()用于将对象转变为键值对数组

Object.entries()和Object.fromEntries()的联系

其实他俩是一个逆运算,一个是将对象转化为二维数组,一个是将二维数组转化为对象

trimStart和trimEnd

一个用于删除字符串前面的空白,一个用于删除后面的

flat

当是二维数组的时候直接就变一维了:

当是三维数组的时候:

把5、6那一层数组展开了

那么如果我们想要把7、8那一层的也解开呢?

需要在flat里面传入一个参数,这个参数表示可展开深度,三维数组可展开深度为2,因此写入2之后三维数组就变一维了(默认该参数值为1),如上图

flatMap

原先我们用map(js的map跟python一样)对数组操作,如上图,但是如果我们的回调函数返回的结果是一个数组,或者说是一个复杂结构:

我们发现整个结果就会变成一个二维数组,如上图,这个时候如果我们想把这个结果变成一个一维数组,就可以用flatMap了:

他相当于是map和flat两个操作的结合

Symbol.prototype.description

就是对Symbol里面的注释字符串的提取

ES11

私有属性

属性前面加#的就是私有属性,不加#就是公有属性

要访问的话只能在类内部写方法访问:

Promise.allSettled

接收Promise数组,返回一个Promise对象,而且返回的Promise对象永远是成功的状态,且返回的值是一个数组,里面是一个个对象,装着每一个Promise的状态和值

我们发现返回的Promise状态是成功的。

上面传了两个成功的Promise,那如果是失败的呢?

这里我们把第二个Promise设置为失败的

返回结果还是一个成功的Promise

其中返回的值的第二个显示第二个Promise的状态是失败的,而且返回了“出错啦!”这个信息

Promise.all

这个不解释了

Promise.all和Promise.allSettled的应用场景

两者都是在处理批量异步任务的时候用的

如果我们想要看到所有异步任务的返回值,就用.allSettled;

如果我们想要每一个异步任务都成功才能继续往下执行,就用.all

String.prototype.matchAll

.matchAll方法使得匹配到的多个内容变成可迭代对象(有next方法)可以用for of遍历,也可以用扩展运算符做展开

可选链操作符

原先我们取数据中的某个属性,比方说上图的host,应该先做一下判断,先判断config是否真的有,如果有再进一步取数据,如上图的 config && config.db && config.db.host

现在有了可选操作链:

可以达到相同效果

动态import

原先的静态import时,我们会在一个入口文件里大量的import,也不管这个模块会在当前文件使用还是在未来的某个时刻去使用,就是一股脑地把模块统统导进来,因为是有依赖关系的。这样的话就不能实现按需加载(懒加载)

模拟:

上图就是静态的导入

import函数

使用import函数来实现动态导入:

import函数返回一个Promise,可以用.then拿到导入的模块中的那些export的方法,比方说这里我们可以用module.hello()来调用另外一个文件中的hello()方法(当然这个hello必须是被export的方法):

当然这个方法是不影响执行效率的,反而能提高加载效率

BigInt(大整形)

直接在int型后面加n

使用BigInt函数转换n

注意!不能将浮点型的数转换成大整形

用途场景

主要用于大数值的运算

比方说我们声明一个最大安全整形,并给他加1再加2:

我们会发现第三个数他是不对的,她不能再去表示一个更大的整形结果了

现在用BigInt给他做一个转换

注意!普通的整形无法跟BigInt型的大整形直接运算,会报错,所以在上面这个案例里面我们还需要把普通整形转换为大整形,之后再与大整形一起运算:

现在就没有问题了

globalThis

无论执行环境是浏览器、nodejs还是其他的什么,这个东西始终指向全局对象,当我们想使用全局对象的时候,啥也别想了,直接用globalThis即可

在浏览器下,它指向的就是window

在nodejs下,它指向全局对象global