关于javascript:ECMAScript-2020ES11新特性简介

8次阅读

共计 3778 个字符,预计需要花费 10 分钟才能阅读完成。

简介

ES11 是 ECMA 协会在 2020 年 6 月发行的一个版本,因为是 ECMAScript 的第十一个版本,所以也称为 ES11.

明天咱们解说一下 ES11 的新个性。

ES11 引入了 9 个新个性,咱们接下来一一解说。

动静 imports

在 ES11 之前,咱们能够应用上面的形式进行模块的导入:

import * as TestModule from "./test-module.js";

然而下面的导入形式会有一些问题,首先是效率的问题,所有的 module 都须要在首次加载的时候导入,会导致程序效率的升高。另外下面的模块名字是写死的,不能够在程序运行的时候进行动静批改。

也就是说下面的模块导入形式,不能对模块进行动静导入,或者按需导入,在应用上有诸多的不便。

为了解决这个问题,ES11 引入了新的 import() 办法,应用这个办法,你能够对模块进行动静导入,并且通过设置模块名为变量的模式,能够对模块名进行动静批改,十分的神奇。咱们看一个具体的应用例子:

const baseModulePath = "./baseModules";
const btnImportModule = document.getElementById("btnImportModule");
let userList = [];

btnImportModule.addEventListener("click", async e => {const userModule = await import(`${baseModulePath}/users.js`);
  
  userList = userModule.getUsers();});

下面代码中咱们定义了一个根本的 Module 门路,通过点击页面上的按钮,能够动静的加载一个 users.js 模块,而后调用该模块的 getUsers() 办法,取得 userList 列表。

import.meta

除了动静引入模块之外,import 还提供了一个元属性 meta, 它蕴含了以后引入的模块的信息,目前他外面有一个 url 属性,代表模块被援用的 URL。如果想应用 URL 信息,那么能够在代码中应用 import.meta.url。

export 增强

import 是在 ECMAScript 2015 中引入的,次要被用来做模块的引入,import 能够引入整个模块,也能够引入局部模块。如下所示:

import {something} from "./test-module.js";
import * from "./test-module.js";

和 import 对应的就是 export,同样能够 export 所有或者局部,如下所示:

export {something} from "./test-module.js";
export * from "./test-module.js";

通常状况来说,下面讲的 import 和 export 曾经够用了,然而对于导出模块须要重命名的状况,咱们不能间接导出,而是必须先在 import 的时候进行重命名,而后再应用 export 将重命名的模块导出:

import * as myModule from "./test-module.js";
export {myModule};

如果应用 export 的加强,则不须要应用 import,间接应用 export 导出即可:

export * as {myModule} from "./test-module.js";

BigInt

ES11 引入了新的数据类型 BigInt,在这之前,javascript 中示意数字的对象是 Number,它能够示意 64-bit 的浮点类型数字。当然它也能够代表整数,然而整数示意的最大值是 2^53, 也能够用 Number.MAX_SAFE_INTEGER 来示意。

一般来说 Number 曾经够用了,然而如果在某些状况下须要对 64-bit 的整数进行存储或者运算,或者要示意的范畴超过了 64-bit 的话,Number 就不够用了。

怎么办呢?如果只是存储的话,能够存储为字符串,然而第二种字符串就不实用了。于是引入了 BigInt 来解决这个问题。要示意 BigInt,只须要在数字的前面加上 n 即可。

const bigInt = 112233445566778899n;

或者应用构造函数来结构 bigInt:

const bigInt = BigInt("112233445566778899");

能够应用 typeof 来查看 bigInt 的类型。要留神的是尽管 Number 和 BigInt 都代表的是数字,然而两者是不能混用的,你不能将一个 Number 和一个 BigInt 相加。这会报 TypeError 异样。

如果非要进行操作,那么能够应用 BigInt 构造函数将 Number 转换成为 BigInt 之后再进行。

matchAll()

正则表达式的匹配是一个十分常见的操作,通常咱们应用 regExp.exec 来进行正则的匹配,举个正则匹配的例子如下:

const regExp = /yyds(\d+)/g;
const text = 'yyds1 is a very good yyds2';
let matches;

while ((matches = regExp.exec(text)) !== null) {console.log(matches);
}

下面的代码运行后果如下:

["yyds1","1"]
["yyds2","2"]

咱们失去了所有匹配的值。不过须要应用一个循环来进行遍历,应用起来有诸多的不便,为了简略起见,ES11 引入了 matchAll() 办法。这个办法能够简略的返回一个遍历器,通过遍历这个遍历器,就能够失去所有的匹配的值,如下所示:

const regExp = /yyds(\d+)/g;
const text = 'yyds1 is a very good yyds2';
let matches = [...text.matchAll(regExp)];

for (const match of matches) {console.log(match);
}

globalThis

对于 javascript 来说,不同的环境对应的全局对象的获取形式也是不同的,对于浏览器来说通常应用的是 window,然而在 web worker 中应用的是 self,而在 nodejs 中应用的是 global。

为了解决在不同环境中的全局对象不同的问题,ES11 引入了 globalThis,通过这个全局对象,程序员就不必再去辨别到底是在哪个环境下了,只须要应用 globalThis 即可。

Promise.allSettled()

自从 Promise 引入之后,有两个办法能够对 Promise 进行组合,别离是 Promise.all() 和 Promise.race(),他们别离示意返回所有的 Promise 和返回最快的那个。

对于 Promise.all() 来说,它会期待所有的 Promise 都运行结束之后返回,如果其中有一个 Promise 被 rejected,那么整个 Promise.all() 都会被 rejected。在这种状况下,如果有一个 Promise 被 rejected,其余的 Promise 的后果也都获取不了。

为了解决这个问题,ES11 引入了 Promise.allSettled() 办法,这个办法会期待所有的 Promise 完结,不论他们是否被 rejected, 所以能够应用上面的代码取得所有的后果,而不论其中是否有 Promise 呈现问题。

const promises = [promise1("/do1"), promise2("/do2")];
const allResults = await Promise.allSettled(promises);
const errors = results
  .filter(p => p.status === 'rejected')
  .map(p => p.reason);

?? 操作符

?? 操作符是一个判断是否为空而后赋值的操作,如果没有这个操作符,咱们通常应用 || 来简略的进行这个操作,如下所示:

const yourAge = someBody.age || 18

下面的代码意思是如果 someBody.age 是空,那么就将 yourAge 设置成为 18。

然而下面代码有个问题,如果 someBody.age=0 的话,上述逻辑也成立。应用??操作符能够解决这个问题。

const yourAge = someBody.age??18

?. 操作符

咱们有时候在获取某个对象的属性的时候,须要进行对象的 null 判断,否则从 null 对象中取出属性就会报错,然而通常的?: 操作符应用起来太简单了,如果有多个对象和属性连写的状况下更是如此,如果应用?. 操作符就会简略很多:

const age = school?.class?.student?.age;

如上所示,这个一个非常复杂的连写操作,然而应用?. 就变得很简略。

同样?. 还能够用在对象的办法上:

const age = student.getAge?.();

下面代码示意,如果 student 的 getAge 办法存在,则调用,否则返回 undefined。

总结

事实上所有的古代浏览器基本上都反对 ES11 了,IE 除外。大家能够纵情尝试 ES11 的新特色。

本文已收录于 http://www.flydean.com/ecmascript-11/

最艰深的解读,最粗浅的干货,最简洁的教程,泛滥你不晓得的小技巧等你来发现!

欢送关注我的公众号:「程序那些事」, 懂技术,更懂你!

正文完
 0