zoukankan      html  css  js  c++  java
  • ECMAScript 2021(ES12)新特性简介

    简介

    ES12是ECMA协会在2021年6月发行的一个版本,因为是ECMAScript的第十二个版本,所以也称为ES12.

    ES12发行到现在已经有一个月了,那么ES12有些什么新特性和不一样的地方呢?一起来看看吧。

    基本上ES12引入了replaceAll方法用于对String进行操作,Promise.any用于对Promise进行组合操作,AggregateError用于表示多个错误的集合,新的逻辑操作符??=, &&=, ||=,弱引用WeakRef,FinalizationRegistry用于垃圾回收的注册,一个数字的分隔符1_000,更加精准的数组sort方法Array.prototype.sort。

    下面本文将会一一进行讲解。

    replaceAll

    熟悉java的朋友应该都知道,java中有两个进行字符串替换的方法,分别是replace和replaceAll,他们的区别在于replace是替换字符串,而replaceAll是进行正则表达式匹配。

    但是在javascript中两者的涵义有所不同,在JS中replace是替换第一个出现的字符串,而replaceAll就是字面上的意思替换所有的字符串,我们举个例子:

    const string="flydean is a good fly"
    console.log(string.replace("fly", "butterfly"));
    
    

    上面的值返回:

    butterflydean is a good fly
    
    

    如果改用replaceAll:

    const string="flydean is a good fly"
    console.log(string.replaceAll("fly", "butterfly"));
    butterflydean is a good butterfly
    
    

    私有方法

    自从JS有了类的概念之后,就可以在类中定义方法,并通过实例化之后的类进行调用,如下所示:

    class Student {
      getAge() {
        console.log("永远18岁")
      }
    }
    
    student= new Student();
    student.getAge();
    
    

    上面代码运行结果:

    "永远18岁"
    

    但是如果我们不希望getAge()方法直接暴露给外部使用,也就是说希望getAge()是一个私有方法,那么只需要在方法前面加上#即可。

    class Student {
      #getAge() {
        console.log("永远18岁")
      }
    }
    
    student= new Student();
    student.getAge();
    
    

    同样运行,那么会得到下面的错误提示:

    Error: student.getAge is not a function
    

    怎么处理呢?我们知道私有方法是可以在方法内部调用的,那么只需要创建一个公有方法,然后在这个公有方法中调用私有方法即可,如下所示:

    class Student {
      #getAge() {
        console.log("永远18岁")
      }
      
      getPublicAge(){
        this.#getAge();
      }
     
    }
    
    student= new Student();
    student.getPublicAge();
    

    我们可以得到同样的结果。

    私有属性

    上面讲到了私有方法,那么对于私有属性是怎处理的呢?

    通常,对于属性,我们可以以get修饰符来进行修饰,然后就可以直接通过属性名来访问了:

    class Student {
      get Age() {
        return 18;
      }
     
    }
    
    student= new Student();
    console.log(student.Age);
    
    

    结果我们会得到18这个输出。

    同样,可以在属性名前面加上#,让其变成私有变量,如下所示:

    class Student {
      get #Age() {
        return 18;
      }
     
    }
    
    student= new Student();
    console.log(student.Age);
    
    

    上面代码将会输出undefined。

    要想访问上述的私有属性,则可以用公有属性去调用私有属性方法:

    class Student {
      get #Age() {
        return 18;
      }
       get publicAge() {
        return this.#Age
      }
    }
    
    student= new Student();
    console.log(student.publicAge);
    

    非常好用。

    Promise.any() 和 AggregateError

    promise.any可以返回任意一个提前resolve的结果,在现实的应用中,这种情况是非常常见的,我们来模拟一个例子:

    const prom1 = new Promise((resolve, reject) => {
      setTimeout(
        () => resolve("promise one"),
        Math.floor(Math.random() * 100)
      );
    });
    const prom2 = new Promise((resolve, reject) => {
      setTimeout(
        () => resolve("promise two"),
        Math.floor(Math.random() * 100)
      );
    });
    const prom3 = new Promise((resolve, reject) => {
      setTimeout(
        () => resolve("promise three"),
        Math.floor(Math.random() * 100)
      );
    });
    
    (async function() {
      const result = await Promise.any([prom1, prom2, prom3]);
      console.log(result); 
    })();
    
    

    上述代码可以随机输出promise one,promise two,promise three。

    如果将上述代码改成所有的都reject,那么会抛出AggregateError:

    const prom1 = new Promise((resolve, reject) => {
      setTimeout(
        () => reject("promise one rejected"),
        Math.floor(Math.random() * 100)
      );
    });
    const prom2 = new Promise((resolve, reject) => {
      setTimeout(
        () => reject("promise two rejected"),
        Math.floor(Math.random() * 100)
      );
    });
    const prom3 = new Promise((resolve, reject) => {
      setTimeout(
        () => reject("promise three rejected"),
        Math.floor(Math.random() * 100)
      );
    });
    
    try{
    (async function() {
      const result = await Promise.any([prom1, prom2, prom3]);
      console.log(result); 
    })();
    } catch(error) {
      console.log(error.errors);
    }
    
    
    

    报的错如下:

    Uncaught (in promise) AggregateError: No Promise in Promise.any was resolved
    
    

    注意,必须是所有的promise都被reject之后才会抛出AggregateError,如果有部分成功,那么将会返回成功的结果。

    数字分隔符

    这个新特性是为了方便程序员看代码而出现的,如果数字比较大,那么看起来就不是那么一目了然,比如下面的长数字:

    const number= 123456789;
    
    

    一眼看不出这个数字的体量到底是多大,所以ES12提供了数字分隔符_。

    分隔符不仅可以分割十进制,也可以分割二净值或者十六净值的数据,非常好用。

    const number = 1_000_000_000_000;
    const binary = 0b1010_0101_1111_1101;
    const hex = 0xAF_BF_C3;
    
    

    上面例子分别代表了十进制,二进制和十六进制的数据,非常直观好用。

    新的逻辑操作符

    我们知道&& 和 || 是被来进行逻辑操作的运算符。

    比如:

    1 && 2 
    1 || 2 
    
    

    等操作,ES12提供了&& 和||的二元操作符,如下:

    var x = 1;
    var y = 2;
    x &&= y;
    x ||= y;
    
    

    另外还提供了??的二元操作符,如:

    var x;
    var y = 2;
    x ??= y;
    
    

    上面代码的意思是,判断x是不是空,如果是空那么将y的值赋给x。

    总结

    ES12的几个新特性还是挺实用的,大家可以尝试一下。

    本文已收录于 http://www.flydean.com/ecmascript-12/

    最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧等你来发现!

    欢迎关注我的公众号:「程序那些事」,懂技术,更懂你!

  • 相关阅读:
    2021.5.16 Android聊天功能
    2021.5.15 Android Gestures示例
    2021.5.14 程序员修炼之路:从小工到专家阅读笔记02
    KL 散度和交叉熵
    UBOOT学习
    UCOSII学习
    cortex-M3/M4体系学习
    一步步写RTOS
    38 操作系统-中断处理与特权级转移
    MDK、IAR将变量定义到指定位置
  • 原文地址:https://www.cnblogs.com/flydean/p/15319158.html
Copyright © 2011-2022 走看看