ES12 5 个新特性

80 阅读3分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 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 回收了。