ES2020新特性抢先看

947 阅读3分钟

String.property.matchAll()

伴随着es2020的到来,matchAll函数也正式来到了stage4阶段了,我们先看下这个函数会作用。

作用

matchAll() 方法返回一个包含所有匹配正则表达式的结果分组捕获组的迭代器。

语法

str.matchAll(regexp)

参数

regexp: 是一个正则表达式对象,如果传的不是一个正则表达式对象,那么会隐式的调用new Regexp()来将其转换为一个正则表达式对象

返回值

返回一个迭代器

获取所有的匹配项

首先我们来看一个例子,在matchAll函数出现之前,我们如果想要获取一个字符串中所有的匹配项,我们应该这样做

const regexp = /[a-z]*(ball)/g;
const str = 'table football, basketball';
let match;

while ((match = regexp.exec(str)) !== null) {
    console.log(`${match[0]} start=${match.index} end=${regexp.lastIndex}.`);
}

使用exec函数,然后通过循环来实现获取所有的匹配项,当有了matchAll()方法之后,他就变得简单了

const regexp = /[a-z]*(ball)/g;
const str = 'table football, basketball';
let match;

match = str.matchAll(regexp);
for(let i of match) {
    console.log(i);
}

注意:在我们使用matchAll的时候,必须要加上"/g"进行全局匹配,否则只会返回首个匹配!!! 20210324补充

大家在想他都叫matchAll了为什么还要加上/g进行全局匹配呢?最近发现了一个问题,通过改变参数的形式我们可以不带/g

如果我们给matchAll的第一个参数换为字符串,那么matchAll函数会自动添加/g

for(let i of '1232342'.matchAll('2')) {
    console.log(i);
}

image.png 通过上面我们就可以看到了,通过字符串的形式可以解决

捕获组

因为当使用match()和/g标志方式获取匹配信息时,捕获组会被忽略

var regexp = /t(e)(st(\d?))/g;
var str = 'test1test2';
str.match(regexp); 
// Array ['test1', 'test2']

但是当我们使用matchAll的时候,我们是可以捕获组的

var regexp = /t(e)(st(\d?))/g;
var str = 'test1test2';
let array = [...str.matchAll(regexp)];
console.log(array);

我们可以看到,我们已经将组捕获了

import()动态导入

之前我们使用import大部分都是静态导入的,例如这样import a from "xx",es2020中推出了动态导入,格式如下

import(`xxx`) //注意和静态导入的格式区别

接下来介绍一下动态导入的优点。

  1. 首先可以优化性能问题,我们可以在需要引入的时候在导入某个文件,而不是在当前组件加载时就直接导入文件
  2. 我们可以在动态导入后进行一系列的操作,捕获操作或者其他操作都可以 我们看一段代码,就可以知道他的好处了
const main = document.querySelector("#main");
main.addEventListener("click", e => {
      e.preventDefault();
      import(`./section-modules/${link.dataset.entryModule}.js`)
        .then(module => {
          console.log(0);
        })
        .catch(err => {
          main.textContent = err.message;
        });
    });

上面这段代码是我们在点击id为main这个元素的时候才会导入这个文件,并且导入之后可以做一系列的操作。

bigInt

在es2020中正式将bigInt作为一种新的数据类型加入到js中

bigInt有两种使用方式

  1. let a = 11111n
  2. let a = BigInt(9007199254740);

bigInt的出现使得我们可以计算一些比较大的数了

var bigNumRet = 9007199254740993n+ 9007199254740993n; // -> -> 18014398509481986n

注意: 在我们使用typeof对bigInt类型的数据进行操作的时候,返回就是bigInt typeof 9007199254740993n; // -> "bigint"

promise.allSelected()

在介绍这个函数之前,我们首先看一下const p =promise.all([p1,p2,p3])这个函数, 这个函数会接收一个数组作为参数,同时数组内的每一个数组都是一个promise对象,如果数组内的每一个promise都是fullfilled,那么最后的p就是fullfilled的状态,但是只要有一个是rejected,那么p的状态就会是rejected,其他的promise都不会执行了

如果我们想把所有的promise都执行完呢?此时我们就可以使用promise.allSelected,他会将当前数组内所有的promise都执行完后,将所有的状态都放到一个数组内

const promise1 = Promise.resolve(3);
const promise2 = new Promise((resolve, reject) => setTimeout(reject, 100, 'foo'));
const promises = [promise1, promise2];
 
Promise.allSettled(promises).
  then((results) => results.forEach((result) => console.log(result.status)));
 
// expected output:
// "fulfilled" "rejected"

Optional Chaining 可选链运算符

我们先看个例子,在看可选链运算符怎么使用

当我们想要去访问一个深层次不存在的属性时,我们可能会这样做

let person = {
    age: 14,
    name: 'wang'
    parent: {
        fa: 'wang'
    }
} 

console.log(person && person.parent && person.parent.mo)//这样才不会报错

但是有没有觉得这样访问有一些麻烦呢?此时我们的通过可选链运算符就可以起作用了,我们先来看一下可选链运算符的真面目 ?. 小朋友,你是否有很多问号???哈哈,没错,可选链运算符就是这样子的,有了可选链运算符之后,我们可以直接这么写

person?.parent?.mo 

没错,就是如此的简单

空值合并运算符

有了上面那个可选链运算符,他是比较奇葩的一种写法,我们接下来介绍的这个空值合并运算符也是比较奇葩的??没错,他就是这样子,我们来使用一下它

let a = null ?? 'default'
console.log(a) // -> default

通过上面这个例子我们可以看出来, ??好像和 || 功能类似啊,没错,??的出现就是为了弥补||的不足,首先我们在使用||的时候,当遇到''的时候,会将其识别为falsy值,所以输入的是||后面的值,但是我们在使用??则不同

let a = '' || 'a'
a // -> 'a'

let b = '' ?? 'a'
b // -> ''

这就是我们说的2020的部分新特性了,还有一些会后续补上