ES2020/2021

背景

今天看阮老师的科技周刊的时候,里头提到了ES2021(作者默认所有的提案最终都会被通过),正好借此梳理一下,ES2020和ES2021,个人使用过的以及后续可能会使用的一些功能,所以这篇不是科普类型,纯属个人喜好的记录。

开始

空值合并运算符:??

**??**是一个逻辑操作符,当左侧的操作数为 null 或者 undefined 时,则返回右侧操作数,否则返回左侧操作数。所以该运算符完美适配默认值的场景。

1
2
3
4
5
6
7
const foo = null ?? 'default string';
console.log(foo);
// expected output: "default string"

const baz = 0 ?? 42;
console.log(baz);
// expected output: 0

多说一句:

设置默认值以前常用的是:**||**(逻辑或操作符),但是都知道不用用它作为有false和0的情况(因为||**判断时,会把值转换为布尔值,而false和0转为布尔值时都是false,所以对于数字类型和布尔类型的用||设置默认值是不合理的+)

可选的链接运算符:?.

嵌套对象时特别好用。表达式还短。

如果引用为空(null 或 undefined),则表达式会短路返回 undefined。

1
2
3
4
5
6
7
8
9
10
11
12
13

if( a && a.b && a.b.c){
//do something...
}
//可换成:
if( a?.b?c){
//do something...
}


const a={}
const test=a?.b?.c
// expected output: undefined
Promise.any() and AggregateError

Promise.any()方法接受一组 Promise 实例作为参数,包装成一个新的 Promise 实例。只要参数实例有一个变成fulfilled状态,包装实例就会变成fulfilled状态;如果所有参数实例都变成rejected状态,包装实例就会变成rejected状态

阮一峰 ECMAScript 6 (ES6) 标准入门教程 第三版

Promise.race和Promise.any

Promise.any()Promise.race()方法很像,只有一点不同,就是不会因为某个 Promise 变成rejected状态而结束。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Promise.race([
new Promise((resolve, reject) => setTimeout(reject, 200, 'Third')),
new Promise((resolve, reject) => setTimeout(resolve, 1000, 'Second')),
new Promise((resolve, reject) => setTimeout(resolve, 2000, 'First')),
])
.then(value => console.log(`Result: ${value}`))
.catch (err => console.log(err))
// expected output: Third


Promise.any([
new Promise((resolve, reject) => setTimeout(reject, 200, 'Third')),
new Promise((resolve, reject) => setTimeout(resolve, 1000, 'Second')),
new Promise((resolve, reject) => setTimeout(resolve, 2000, 'First')),
])
.then(value => console.log(`Result: ${value}`))
.catch (err => console.log(err))
// expected output: Second
globalThis

全局属性 globalThis 包含全局的 this 值,类似于全局对象(global object)。globalThis 提供了一个标准的方式来获取不同环境下的全局 this 对象(也就是全局对象自身)不用在考虑不同的环境获取方式不一样的问题。

String replaceAll()
1
2
const newStr = str.replaceAll(regexp|substr, newSubstr|function).
// 当使用一个 `regex`时,您必须设置全局(“ g”)标志

replaceAll(pattern,replacement) 方法返回一个新字符串,新字符串所有满足 pattern 的部分都已被replacement 替换。pattern可以是一个字符串或一个 RegExpreplacement可以是一个字符串或一个在每次匹配被调用的函数。

old:

1
2
3
4
5
6
7
8
9
const str = "zhangsan is wangmazi's 舅子,wangmazi is zhangsan's 妹夫";
const newStr = str.replace("is", "isn't");
console.log(newStr);
// expected output:zhangsan isn't wangmazi's 舅子,wangmazi is zhangsan's 妹夫

// 替换所有,只能用正则
const newStr = str.replace(/is/g, "isn't");
console.log(newStr);
//expected output: zhangsan isn't wangmazi's 舅子,wangmazi isn't zhangsan's 妹夫

new:

1
2
3
4
const str = "zhangsan is wangmazi's 舅子,wangmazi is zhangsan's 妹夫";
const newStr = str.replaceAll("is", "isn't");
console.log(newStr);
// expected output: zhangsan isn't wangmazi's 舅子,wangmazi isn't zhangsan's 妹夫
逻辑赋值运算符:(&&= ||= ??=)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
x ||= y;
// 等同
x || (x = y);

x &&= y;
// 等同
x && (x = y);
// 或者
if(x) {
x = y
}

x ??= y;
// 等同
x ?? (x = y);


// 比如
let x = 1;
let y = 2;
x &&= y;
console.log(x);
//expected output: 2

下划线作为数字分隔符
1
2
3
4
5
6
7
8
const billion = 1000_000_000;
console.log(billion);
//expected output:1000000000
const trillion = 1000_000_000_000n;
console.log(trillion.toString());
//expected output: "1000000000000"
console.log(1000_000_000 === 1000000000);
//expected output: true

了解更多

Promise.allSettled

我通常在页面初始化需要多个数据且相互之间又没联系的时候会用它。

**Promise.allSettled()**方法接受一组Promise 实例作为参数,包装成一个新的 Promise 实例。只有等到所有这些参数实例都返回结果(不管是fulfilled还是rejected),返回结果是一个对象数组,每个对象表示对应的promise结果。

当有多个彼此不依赖的异步任务成功完成时,或者我们不关心异步操作的结果,只关心每个promise的结果时,通常使用它。

1
2
3
4
5
6
7
8
9
10
const p1 = new Promise((resolve, reject) => setTimeout(resolve, 1000,'failed'));
const p2 = new Promise((resolve, reject) => setTimeout(reject, 2000,'a'));
const p3 = new Promise((resolve, reject) => setTimeout(resolve, 3000,'b'));
// 返回值对象:fulfilled时,对象有value属性,rejected时有reason属性
Promise.allSettled([p1, p2, p3]).then(values => console.log(values));

//expected output: Array
// 0: {status: "fulfilled", value: "failed"}
// 1: {status: "rejected", reason: "a"}
// 2: {status: "fulfilled", value: "b"}

相比之下,Promise.all() 更适合彼此相互依赖或者在其中任何一个reject时就需要立即结束的场景。即Promise.all() 其实无法确定所有请求都结束。

参考资料:

https://github.com/tc39/ecma262/releases

https://backbencher.dev/javascript/es2021-new-features

https://mp.weixin.qq.com/s?__biz=MzUxMzcxMzE5Ng==&mid=2247494289&idx=2&sn=d8a0ef1443954b7a5bae79ec90411cbd&chksm=f9525fd2ce25d6c4f1d1ac2ab8ce6b7034f68f484881a3548549648dfe5aedd427c7b930385b&scene=21#wechat_redirect

https://tc39.es/ecma262/2021/#sec-web-scripting

https://www.telerik.com/blogs/learn-new-features-introduced-javascript-es2021

https://blog.fundebug.com/2019/08/28/javascript-nullish-coalescing/

本文引用的内容,如有侵权请联系我删除,给您带来的不便我很抱歉。