开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第17天,点击查看活动详情
1)新的逻辑运算符
JavaScript 新增了三个新的逻辑运算符,分别是 &&= 、 ||= 以及 ??= 。下面我们来看看它们的用法:
&&= 运算符:
在深入介绍细节之前,先来看下面这段代码:
let a = 1;
let b = 2;
a &&= b;
console.log(a) // 输出2
a&&=b 和下面这段代码的效果一样:
if(a){
a = b
}
这个逻辑运算符的意思是,如果变量 a 为真值(在这个例子中是真值,因为它是一个非0数字),那么就将 b 赋值给 a。因此我们最后打印 a 的时候输出的是 2 不是 1。
||= 运算符:
看下面的代码:
let a = 1;
let b = 2;
a ||= b;
console.log(a); // 输出1
这个运算符和上面的运算符相反。只有在 a 为假值的时候,他才会被赋值为 b。上面的代码等价于:
if(!a){
a = b
}
??= 运算符
只有变量是 null 或者 undefined 的时候才执行赋值。看下面的代码:
let a;
let b = 2;
a ??= 1;
console.log(a) // 输出1
// 等价于下面的代码
// if(a === null || a === undefined) {
// a = 1
// }
在上面的例子中,没有赋值的 a 默认为 undefined,所以它被赋值为 1。
2)字符串 replaceAll 方法
之前,我们经常使用字符串的 replace 方法,用某个指定字符去替换字符串中的某个部分。但这个方法有一个限制,那就是只能替换第一个匹配的字符或者字符串。为了能够匹配并替换全部的字符或者字符串,我们不得不使用正则表达式。比如:
// 不使用正则
let str = 'JS is everywhere. JS is amazing!';
console.log(str.replace('JS', 'JavaScript')); // 输出 'JavaScript is everywhere. JS is amazing!'
// 使用正则
let str = 'JS is everywhere. JS is amazing!';
console.log(str.replace(/JS/g, 'JavaScript')); // 输出 'JavaScript is everywhere. JavaScript is amazing!'.
但有了 replaceAll 方法,我们就不再需要使用正则表达式了:
let str = 'JS is everywhere. JS is amazing!';
console.log(str.replaceAll('JS', 'JavaScript')); // 输出 'JavaScript is everywhere. JavaScript is amazing!'.
replaceAll 方法可以替换所有匹配的字符或者字符串。
3)使用下划线分割整数
有时候我们可能遇到很大的整数,因此数不清具体有多少个数字,不知道这个数字是百万还是十亿。
但有了这个新特性之后,可读性大大增加。我们可以使用下划线分割大整数,且不需要将其转化为字符串。就像这样:
let number = 1_000_000_000; // 字面量可以直接使用下划线
console.log(number) // 1000000000 (打印的时候可以获取实际的数字)
4)Promise.any()
Promise.any() 可以接收多个可迭代的 promise 并返回首先 fulfilled 的 promise。看下面的例子:
const p1 = new Promise(resolve => setTimeout(resolve, 500, 'First'));
const p2 = new Promise(resolve => setTimeout(resolve, 800, 'Second'));
const p3 = Promsie.reject(1);
const promises = [p1, p2, p3]
Promise.any(promises)
.then(result => {
console.log(result);
}) // 打印'First',因为它首先 fulfilled
.catch(e => {
console.log(e);
})
如果没有一个 promise 达到 fulfilled 状态,则会抛出错误,这里通过调用 catch 方法捕获这个错误。
5)WeakRef 和 Finalizers
WeakRef
WeakRef 指的是弱引用,它允许保持对一个对象的弱引用。被保持的弱引用成为 target。弱引用无法阻止对象被 GC 回收。
PS:GC 可以回收不再被用到的变量,从而释放它们的内存。
看下面的例子:
const weakRefFunc = () => {
const obj = new WeakRef({
name: 'JavaScript'
});
console.log(obj.deref().name);
}
const test = () => {
new Promise(resolve => {
setTimeout(() => {
weakRefFunc();
resolve();
}, 3000)
})
new Promise(resolve => {
setTimeout(() => {
weakRefFunc();
resolve();
}, 5000)
})
}
test();
deref 方法返回一个被保持的 target。如果 target 被 GC 回收了,则会返回 undefined。
在这个例子中,变量 obj 就是被保持的弱引用。
第一次在 test 函数体中调用 weakrefFunc 的时候,毫无疑问会打印 Javascript,但第二次调用的时候就不会打印了,因为变量 obj 作为弱引用已经被 GC 回收了。