ES2020新特性

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

你可能感兴趣的:(javascript,ES2020,es新特性,ecmascript)