阅读 204
ES2021新特性解读| 8月更文挑战

ES2021新特性解读| 8月更文挑战

目录

  1. 提案流程
  2. ES2021新特性

提案流程

一个新特性从提出到最终纳入标准,需要经历5个步骤:

提案流程

提案各阶段内容

ECMAScript标准是TC39(ECMA国际组织第39号技术委员会)制定的,更多有关提案的信息可以到官网上查看:www.ecma-international.org/technical-c…

ES2021新特性

截止目前,2021年已有5个新特性到了stage4:

  1. String.prototype.replaceAll2021
  2. Promise.any
  3. WeakRefs
  4. Logical Assignment Operators
  5. Numeric separators

1、String.prototype.replaceAll

github.com/tc39/propos…

该提案提出在String原型上增加replaceAll()方法:

String.prototype.replaceAll(searchValue, replaceValue)
复制代码
  1. 如果searchValue是字符串,String.prototype.replace只替换第一次出现的searchValue,而String.prototype.replaceAll替换所有出现的searchValue。
  2. 如果searchValue是非全局正则表达式,则String.prototype.replace替换单个匹配项,而String.prototype.replaceAll抛出异常。

除了以上两点,replaceAllreplace在其他情况下表现一致(如不会改变原字符串、返回一个新的字符串、第二个参数可以是一个新的子串或一个返回新子串的函数等)。

用法如下:

字符串全局替换
const queryString = 'q=query+string+parameters';
const withSpaces = queryString.replaceAll('+', ' '); // 'q=query string parameters'
复制代码
全局正则替换
const a='xxxx';
const b = a.replaceAll(/x/g,'y'); // 'yyyy'
复制代码
非全局正则抛出异常
const a='xxxx';
const b = a.replaceAll(/x/,'y');
复制代码

比如chrome,提示如下错误:

Uncaught TypeError: String.prototype.replaceAll called with a non-global RegExp argument
    at String.replaceAll (<anonymous>)
    at <anonymous>:2:13
复制代码

v8源码:github.com/v8/v8/commi…

浏览器兼容性:

2、Promise.any

github.com/tc39/propos…

多个Promise请求,取最先成功(resolve)的那个请求;只有当所有请求都失败(reject),才执行catch。

any和race不一样,race是始终取最先返回的那个请求,不管这个请求是成功还是失败(成功走resolve失败走catch),而any只取最先成功的。

用法:

    const p1 = new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve("p1 success")
      }, 1000)
    })
    const p2 = new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve("p2 success")
      }, 500)
    })
    Promise.any([p1, p2]).then((result) => {
      console.log(result) // "p2 success"
    }).catch((error) => {
      console.log(error)
    })
复制代码

浏览器兼容性:

3、WeakRefs

github.com/tc39/propos…

一个对象弱引用类,当一个对象没有任何强引用的时候(即使有弱引用),就会被GC垃圾回收。此时便无法通过弱引用来获取到该对象。

建议不要使用,除非很有必要,因为不同Javascript引擎中的GC行为可能大相径庭,甚至在同一个引擎中的表现都有可能有所差异。

MDN上的计时器例子:

class Counter {
  constructor(element) {
    // Remember a weak reference to the DOM element
    this.ref = new WeakRef(element);
    this.start();
  }


  start() {
    if (this.timer) {
      return;
    }


    this.count = 0;


    const tick = () => {
      // Get the element from the weak reference, if it still exists
      const element = this.ref.deref();
      if (element) {
        element.textContent = ++this.count;
      } else {
        // The element doesn't exist anymore
        console.log("The element is gone.");
        this.stop();
        this.ref = null;
      }
    };


    tick();
    this.timer = setInterval(tick, 1000);
  }


  stop() {
    if (this.timer) {
      clearInterval(this.timer);
      this.timer = 0;
    }
  }
}


const counter = new Counter(document.getElementById("counter"));
counter.start();
setTimeout(() => {
  document.getElementById("counter").remove();
}, 5000);
复制代码

效果如图:

当元素被移除后,element指向的对象变为undefined,控制台输出日志,计时器停止

浏览器兼容性:

4、proposal-logical-assignment

github.com/tc39/propos…

继2020年提出的??空值合并运算符之后,今年又多了三个:||=&&=??= 逻辑操作符。

a ||= b等价于a || (a = b)

a &&= b等价于a && (a = b)

a ??= b等价于a ?? (a = b)

这个提案的灵感来自于Ruby语言。

举个例子:

const a = { duration: 50, title: '' };

a.duration ||= 10;
console.log(a.duration); // 50

a.title ||= 'title is empty.';
console.log(a.title); // "title is empty"
复制代码

浏览器兼容性:

5、Numeric separators

github.com/tc39/propos…

数字分隔符:_,不会改变数字的真实值,只是为了方便代码阅读。支持不同进制:

1_000_000_000_0001_050.95 // 十进制

0b1010_0001_1000_0101 // 二进制

0o2_2_5_6 // 八进制

0xA0_B0_C0 // 十六进制

1_000_000_000_000_000_000_000n // bigint类型
复制代码

注意事项:

  • 不能连着两个下划线(如100__000)
  • 不能出现在数字末尾(如100_)
  • 不能出现在以0开头的数字0后面(如0_1)

这几种情况都会报SyntaxError错误。

浏览器兼容性:

文章分类
前端
文章标签