ES2020新特性

154 阅读4分钟
    1.通过 # 给 class 添加私有变量
    class Counter {
        #number = 10
        increment() {
            this.#number++
        }
        getNum() {
            return this.#number
        }
    }
    const counter = new Counter()
    counter.increment()
    console.log(counter.getNum())    //11
    console.log(counter.#number)    //SyntaxError
    在 ES2020 中,通过 # 可以给 class 添加私有变量。在 class 的外部我们无法获取该值。当我们尝试输出 counter.#number,语法错误被抛出:无法在 class Counter 外部获取它。这样就不需要使用闭包来隐藏不想暴露给外界的私有变量。BigInt

    2.BigInt
    Js 中 Number类型只能安全的表示 - (2 ^ 53 - 1)至 2 ^ 53 - 1 范的值,超出这个范围的整数计算或者表示会丢失精度,我们可以用 BigInt 对象表示不在这个范围内的数。可以通过常规操作进行加、减、乘、除、余数和幂等运算。它可以由数字和十六进制或二进制字符串构造。此外它还支持 AND、OR、NOT 和 XOR 之类的按位运算。唯一无效的位运算是零填充右移运算符(>>>)。

    使用BigInt 有两种方式:1.在整数字面量后面加n。2. BigInt 函数。

    let a = 123n;
    let b = BigInt(456n);

    console.log(typeof a)    //bigint
    console.log(a + b)         //579n

    1n == 1             //true
    1n === 1            //false
    3.空值合并运算符
    来自 undefined 或 null 值的另一个问题是,如果我们想要的变量为 undefined 或 null 则必须给变量设置默认值。例如:

    const a = b || 123;
    当使用 || 运算符将 b 设置为 a 时,如果 b 被定义为 undefined,我们必须设置一个默认值。运算符 || 的问题在于,所有类似于 0,false 或空字符串之类的值都将被我们不想要的默认值覆盖。

    为了解决这个问题,创建了“nullish”合并运算符,用 ?? 表示。有了它,我们仅在第一项为 null 或 undefined 时设置默认值。使用无效的合并运算符,以上表达式将变为:

    const a = b ?? 123;
    4.可选链运算符
    如果要访问对象的深层嵌套属性,则必须通过很长的布尔表达式去检查每个嵌套级别中的属性。必须检查每个级别中定义的每个属性,直到所需的深度嵌套的属性为止,如下代码所示:

    let name = user && user.info && user.info.name;

    let age = user && user.info && user.info.getAge && user.info.getAge();
    如果在任何级别的对象中都有 undefined 或 null 的嵌套对象,如果不进行检查,那么的程序将会崩溃。这意味着我们必须检查每个级别,以确保当它遇到 undefined 或 null 对象时不会崩溃。

    使用可选链运算符,只需要使用?.来访问嵌套对象。而且如果碰到的是 undefined 或 null 属性,那么它只会返回 undefined。通过可选链,可以把上面的代码改为:

    let name = user?.info?.name;
    let age = user?.info?.getAge?.();
    5.Promise.allSettled()
    Promise.allSettled(iterable);


    iterable:一个可迭代的对象,例如Array,其中每个成员都是Promise。
    返回一个在所有给定的promise resolved 或者 rejected的promise,并带有一个对象数组,每个对象表示对应的promise结果。

    const promise1 = Promise.resolve(3);
    const promise2 = new Promise((resolve, reject) => setTimeout(reject, 100, 'foo'));
    const promises = [promise1, promise2];

    Promise.allSettled(promises).
        then((results) => results.forEach((result) => console.log(result.status)));

    // expected output:
    // "fulfilled"
    // "rejected"
    6.dynamic -import
    静态 import 和动态 import() 有各自的特点和使用场景。使用静态 import 来初始绘制依赖关系,考虑到按需加载则使用动态 import() 。

    static import 是没有括号的,dynamic import() 是带括号的。不注意的可能会混淆。用法的区别:

static import: import xxx from 'xxx'  //有声明提升,一般只放在头部位置 dynamic import(): const xxx = import('xxx')  //可以放在任何位置 el.onclick = () => { import(main.js) .then(() => { //... }) } 7.globalThis globalThis 提供了一个标准的方式去获取不同环境下的全局对象。它不像 window 或者 self 这些属性,而是确保可以在有无窗口的环境下都可以正常工作。所以你可以安心的使用 globalThis ,不必担心它的运行环境。

    var getGlobal = function () {
        if (typeof self !== 'undefined') { return self; }
        if (typeof window !== 'undefined') { return window; }
        if (typeof global !== 'undefined') { return global; }
        throw new Error('unable to locate global object');
    };

    var globals = getGlobal();

    if (typeof globals.setTimeout !== 'function') {
        // no setTimeout in this environment! 
    }


    //有了 globalThis 之后,只需要:


    if (typeof globalThis.setTimeout !== 'function') {
        // no setTimeout in this environment!
    }
    参考资料:

    MDN

    prop - tc39.now.sh

    https://github.com/tc39/proposals/blob/master/finished-proposals.md