JavaScript 的 ES2020 版本新功能有:
➡️ String.prototype.matchAll
➡️ import()
按需加载,webpack已解决。
➡️ BigInt
➡️ Promise.allSettled
➡️ globalThis
➡️ for-in mechanics
➡️ 可选链
➡️ 空值合并运算符
可选链操作符
可选链 可让我们在查询具有多个层级的对象时,不再需要进行冗余的各种前置校验
背景:当需要访问嵌套在对象内部好几层的属性时,可能就会得到臭名昭著的错误Uncaught TypeError: Cannot read property...,这种错误,让整段程序运行中止。
修改你的代码来处理属性链中每一个可能的undefined对象;
let nestedProp = obj && obj.first && obj.first.second;
在访问 obj.first.second 之前,要先确认 obj 和 obj.first 的值非 null(且不是 undefined)。 有了可选链式调用 ,可以大量简化类似繁琐的前置校验操作,而且更安全:
let nestedProp = obj?.first?.second;
空位合并操作符
背景:当我们查询某个属性时,经常会给没有该属性就设置一个默认的值。
例如
let c = a ? a : b;//方式1
let c= a || b; // 方式2
上述两个有明显的弊端,会覆盖所有的假值,(0,'',false),这些值可能在某些情况下有效的输入。
let x = {
profile: {
name: '你好',
age: ''
}
}
console.log(x.profile.age || 18) //18
上例中的age的属性为空字符串,却被等同为假值。
解决办法: ES2020提出空位合并操作符,用??表示。如果表达式在??的左侧运算符求值为undefined或null,就返回其右侧默认值。
let c = a ?? b;
// 等价于let c = a !== undefined && a !== null ? a : b;
const x = null
const y = x ?? 500
console.log(y) // 500
Promise.allSettled
Promise.all 具有并发执行异步任务的能力。但它的最大问题就是如果其中某个任务出现异常(reject),所有任务都会挂掉,Promise直接进入 reject 状态。
场景:你的页面有三个区域,分别对应三个独立的接口数据,使用 Promise.all 来并发三个接口,如果其中任意一个接口服务异常,状态是reject,这会导致页面中该三个区域数据全都无法渲染出来,因为任何 reject 都会进入catch回调, 很明显,这是无法接受的。
Promise.all([
Promise.reject({code: 500, msg: '服务异常'}),
Promise.resolve({ code: 200, list: []}),
Promise.resolve({code: 200, list: []})
])
.then((ret) => {
// 如果其中一个任务是 reject,则不会执行到这个回调。
RenderContent(ret);
})
.catch((error) => {
// 本例中会执行到这个回调
// error: {code: 500, msg: "服务异常"}
})
如果并发任务中,无论一个任务正常或者异常,都会返回对应的的状态(fulfilled 或者 rejected)与结果(业务value 或者 拒因 reason),在 then 里面通过 filter 来过滤出想要的业务逻辑结果,这就能最大限度的保障业务当前状态的可访问性,而 Promise.allSettled 就是解决这问题的。
Promise.allSettled([
Promise.reject({code: 500, msg: '服务异常'}),
Promise.resolve({ code: 200, list: []}),
Promise.resolve({code: 200, list: []})
])
.then((ret) => {
/*
0: {status: "rejected", reason: {…}}
1: {status: "fulfilled", value: {…}}
2: {status: "fulfilled", value: {…}}
*/
// 过滤掉 rejected 状态,尽可能多的保证页面区域数据渲染
RenderContent(ret.filter((el) => {
return el.status !== 'rejected';
}));
});
BigInt
Js 中 Number类型只能安全的表示-(2^53-1)至 2^53-1 范的值,即Number.MIN_SAFE_INTEGER 至Number.MAX_SAFE_INTEGER,超出这个范围的整数计算或者表示会丢失精度。
var num = Number.MAX_SAFE_INTEGER; // -> 9007199254740991
num = num + 1; // -> 9007199254740992
// 再次加 +1 后无法正常运算
num = num + 1; // -> 9007199254740992
// 两个不同的值,却返回了true
9007199254740992 === 9007199254740993 // -> true
解决此问题,ES2020提供一种新的数据类型:BigInt。 使用 BigInt 有两种方式:
1:在整数字面量后面加n。
var bigIntNum = 9007199254740993n;
2:使用 BigInt 函数。
var bigIntNum = BigInt(9007199254740);
var anOtherBigIntNum = BigInt('9007199254740993');
注意: 1. BigInt 是一种新的数据原始(primitive)类型。
typeof 9007199254740993n; // -> 'bigint'