ES2020 中对 Javascript 的新增和改进
1、 BigInt - 大整数
大整数的出现,突破了原 Javascript 中最大整数为 pow(2, 53) - 1 的限制
- 原来的限制
let maxNum = Number.MAX_SAFE_INTEGER;
undefined;
maxNum;
9007199254740991;
++maxNum;
9007199254740992;
++maxNum;
9007199254740992;
++maxNum;
9007199254740992;
- 大整数特性
let bigInt = 9007199254740992n;
undefined;
++bigInt;
9007199254740993n;
++bigInt;
9007199254740994n;
++bigInt;
9007199254740995n;
大整数使用方式比较简单,数字后面加个 n 即可。
2、动态引入
Javascript 的动态引入,允许你把 JS 文件作为一个模块动态的引入到你的应用中。这就像你使用 webpack 和 Babel 一样。
这个功能可以帮助你处理按需加载的代码,拆分代码,而且,并不需要 webpack 或者其它模块处理器。如果,你喜欢也可以在 if-else 块中加载代码。
虽然目前在项目中我们也可以使用,使用方法形如:
async function exportDoc() {
if (xxx) {
return false;
}
const { exportWord } = await import("./utils/exportDoc.js");
exportWord("xxx");
}
3、 ?? 空值合并
空值合并可以真正的检查 nullish 值,而不是 falsely 值。
Javascript 中有很多值经过类型转换都会变为 false 而参与判断,该值被称为 falsely 值。如:''、 0、 undefined、 null、 false、 NaN 等。
实际开发中,我们更希望知道某个字段是否为真·空值(undefined、 null),现在就可以直接使用新的空值合并操作符 ??
- 或操作符(||),总是返回真值
"" || "truthy";
("truthy");
0 || "truthy";
("truthy");
undefined || "truthy";
("truthy");
null || "truthy";
("truthy");
false || "truthy";
("truthy");
NaN || "truthy";
("truthy");
- 空值合并操作符(??),总是返回非空(非 undefined、 null)值
"" ?? "truthy";
("");
0 ?? "truthy";
0;
undefined ?? "truthy";
("truthy");
null ?? "truthy";
("truthy");
false ?? "truthy";
false;
NaN ?? "truthy";
NaN;
4、?. 可选链
可选链的出现,大大减少了重复和不必要的空值判断代码。它允许直接访问复杂数据类型(各种 Object )任意层级的属性值而不会报错,如果存在就返回对应 value,否则返回 undefined。
var a = {
key: {
key1: {
key2: {
key3: [0, 1, 2, { key4: true }],
},
},
},
};
如果我想获取 key4 的值
- 过去的写法
if (
a &&
a.key &&
a.key.key1 &&
a.key.key1.key2 &&
a.key.key1.key2.key3 &&
a.key.key1.key2.key3[3]
) {
key4 = a.key.key1.key2.key3[3].key4;
}
true;
- 可选链写法
key4 = a.key?.key1?.key2?.key3?.[3]?.key4;
true;
5、Promise.allSettled
allSettled 的出现,解决了使用 race 和 all 方法处理多个并行 Ajax 或 Promise,响应结果无法捕捉的问题。它接收一组 Promise ,并将所有的处理结果返回 - 不管是 resolved 还是 rejected
const promiseList = [
Promise.resolve({ code: 0 }),
Promise.reject({ code: -1 }),
Promise.reject(new Error('Error occur!!!'))
]
Promise.allSettled(promiseList).then(res => {
const [res1, res2, res3] = res
console.log(res1, res2, res3)
})
{status: "fulfilled", value: {…}}
status: "fulfilled"
value: {code: 0}
__proto__: Object
{status: "rejected", reason: {…}}
reason: {code: -1}
status: "rejected"
__proto__: Object
{status: "rejected", reason: Error: Error occur!!!
at <anonymous>:4:18}
reason: Error: Error occur!!! at <anonymous>:4:18
status: "rejected"
__proto__: Object
6、String.prototype.matchAll
matchAll 是 String 原型链上的一个新增的方法,它接收一个正则表达式作为参数,返回一个迭代器,触发迭代器时,会从前到后依次返回正则匹配的结果
const regexp = /t(e)(st(\d?))/g;
const str = 'test1test2';
const array = Array.from(str.matchAll(regexp)) || [...str.matchAll(regexp)]
console.log(array[0]);
// expected output: Array ["test1", "e", "st1", "1"]
console.log(array[1]);
// expected output: Array ["test2", "e", "st2", "2"]
str.matchAll(regexp)
===========
["test1", "e", "st1", "1", index: 0, input: "test1test2", groups: undefined]
["test2", "e", "st2", "2", index: 5, input: "test1test2", groups: undefined]
RegExpStringIterator {}
7、globalThis
不同平台或宿主环境中,全局对象也有不同,比如在浏览器中是 window ,Node 中是 global,web workers 中是 self。
globalThis 可以无视 js 的运行环境,始终指向全局对象。
- 浏览器中
globalThis === window;
true;
- Node 环境
Welcome to Node.js v12.18.1.
Type ".help" for more information.
> globalThis === global
true
8、导出模块的命名空间
我们很早就能在导入时重新命名
import * as utils from "./utils.js";
现在我们可以这样进行导出了
export * as utils from './utils.js'
===================================
上面的结果等同于现在的用法
import * as utils from './utils.js'
export { utils }
9、明确定义 for-in 的顺序
ECMA 规范中并没有明确定义 for (x in y) 的顺序。尽管浏览器已经实现了一致的顺序,但是现在它已经被添加到 ES2020 的官方规范中了。
<script type="module" src="module.js"></script>
console.log(import.meta); // { url: "file:///home/user/module.js" }
它返回一个包含 url 属性的对象,该属性代表着模块的 URL。它可能是获取脚本的 URL(对于外部脚本来说),或者是包含模块文档的基础 URL(对于内联脚本来说)。