我是靠谱客的博主 体贴电话,最近开发中收集的这篇文章主要介绍ES2021新特性,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

目前,进入stage4的提案已基本确定,所以ES2021(也就是ES12)的新功能也基本确定了,来看一下吧。

惯例,提案戳这

1.String.prototype.replaceAll

之前字符串实例,只有replace方法可以替换生成对应的字符串。第一个参数是匹配模式,可以是字符串,也可以是正则。

如果第一个参数是字符串,那么replace方法最多只会替换一次

所以之前的replace方法其实可以实现现在的replaceAll方法的功能,只需要在正则加上'g'的修饰符即可。

const s = "123asdsa451";
console.log(s.replace("1", "--")); //--23asdsa451
console.log(s.replace(/d/g, "@")); //@@@asdsa@@@

现在提供的replaceAll,如果第一个参数是字符串,那么是会替换所有匹配的字符的。

如果是个正则,那么这个正则必须有'g'的修饰符,否则会报错。

正则的结果和之前的replace方法是一样的

console.log(s.replaceAll("1", "@")); //@23asdsa45@
console.log(s.replaceAll(/1/g, "--")); //@23asdsa45@
console.log(s.replaceAll(/d/g, "@")); //Uncaught TypeError: String.prototype.replaceAll called with a non-global RegExp

另外提一句:所有字符串上的实例方法,都不会修改原字符串。只有可能返回新字符串。

另另外,插一句,提案上说,replaceAll的主要目的是给开发者提供一个更简单直接的操作方式。

2.Promise.any

说到Promise.any,就要先提一下和它有关系的其他几个方法,做一个对比。这些方法的共同点是,参数都是promise数组

  • Promise.all(): 只有参数中所有的promise实例的状态都变成fullfilled,promise.all()的状态才会变成fullfilled,传给回调函数的参数是每个promise的返回值组成的数组。否则状态会变成rejected
  • Promise.race():race的意思是竞争。Promise.race()执行时,如果参数中有一个状态改变,那么Promise.race的状态也会改变(对应的状态就是参数中最先改变状态的promise的状态)
  • Promise.allSettled:所有的参数状态都完成的时候(不管是成功还是失败),回调才会触发。回调函数的参数是一个数组,表示对应的promise的返回值

Promise.any方法的执行方式是,如果参数中有一个promise的状态变成了fullfilled,那么Promise.any的状态就会变成fullfilled,相反,如果参数中所有Promise实例的状态都是rejected,那么Promise.any的状态就会变成rejected

提个题外话:我觉得方法名应该改成Promise.some,和Array.prototype.some的作用方式挺像的,不过也的确有点区别emm

const p1 = new Promise((res, rej) => {
return Promise.resolve().then(() => res(1));
});
const p2 = new Promise((res, rej) => rej(2));
Promise.race([p1, p2]).then(
(a) => {
console.log(a);
},
(b) => {
console.log(b);
}
); //2
Promise.any([p1, p2]).then(
(a) => {
console.log(a);
},
(b) => {
console.log(b);
}
); //1

3.WeakRefs

WeakRefs是一个Class,提案上说一般和FinalizationRegistry Class配合使用,并且一般开发者尽量避免使用。

WeakRef创建实例时,接受一个对象作为参数,返回weakRef实例,这个实例对参数对象有弱引用的关系,也就是这个weakRef对象存在,也不会阻止参数对象的回收。

通过weakRef对象的deref方法,可以获取参数对象。如果参数对象已经被gc回收,那么返回值是undefined

const a = {};
const obj = new WeakRef(a);
const fina = new FinalizationRegistry((v) => {
console.log(v);
});
fina.register(a, "a被回收了");
fina.obj.deref(); //a
console.log(a);
obj.deref(); //undefined 如果a被回收了

因为在浏览器中,内存回收的时间并不是确定的,因为可能有闭包或者内联缓存,所以有的时候一个对象你觉得它被回收了,其实还没有,除此之外,不同js引擎对gc回收的处理也有区别。

所以,对应的FinalizationRegistry的回调触发时机也是无法预知的,如果一些重要逻辑放在FinalizationRegistry的回调里,很容易不会按照你的预期工作。

所以,官方提示这类api能不用就不用。

那么,为什么还会有这个api呢。在某些场景,weakRef还是很有用的。

在有大对象(比如高像素的图片或者大模型),我们在一些场景需要判断对应的数据是否被回收然后做相应的处理,但又不希望因为我们的判断导致该对象一直被引用(这样会导致该对象一直在内存里无法被回收),在这种情况下,用弱引用就可以既不会影响数据被gc回收,也可以获取该数据的状态。

那么WeakMap呢?不行。因为WeakMap的key是弱引用对象,但是值不是,没办法判断值对应的对象是否被内存回收了。

4.Logical Assignment Operators

ES2020新增了可选链和空值合并运算符,这次新增的赋值操作符和是空值合并运算符有点关系的。

空值,就是null和Undefined。

这次新增了??=和||=、&&=三个赋值操作符,

// "Or Or Equals" (or, the Mallet operator :wink:)
a ||= b;
a || (a = b);
// "And And Equals"
a &&= b;
a && (a = b);
// "QQ Equals"
a ??= b;
a ?? (a = b);

??=的意思是,如果左侧的值是空值,那么就把右侧的值赋值给左侧的变量

||=的意思是,如果左侧的值是假值(六大假值),就把右侧的值赋值给左侧的变量。因为此时左侧如果是真值,就会跳过右侧

&&=的意思是,如果左侧的值是真值(假值之外的就是真值),就把右侧的值赋值给左侧的变量。

主要目的是少写一个判断,方便写代码

let a = 0;
let b = null;
let c = 1;
a ??= 1; //a:0
a ||= 1; //a:1
b ??= 1; //b:1
b ||= 2; //b:2
a &&= 1; //a:0
c &&= 2; //c:2

5.Numeric separators

对于数字,比如123456789,一长串看起来很累,所以这次加了下划线作为分隔符,主要是方便阅读(其他语言也有类似的分隔符),对数字本身的大小没有影响。

注意,下划线不能连续,也不能放在开头和结尾,放在开头,就变成字符串了,会被当成变量名,放在结尾会直接报语法错误

const a = 123_3445;
a === 1233445; //true
const b = _123_342;//Uncaught ReferenceError: _123_342 is not defined
const c = 333_344_;//Uncaught SyntaxError: Numeric separators are not allowed at the end of numeric literals

 

ES2021的新功能算比较少的,主要是加了一些方便日常使用的api,没有全新的语法(class fields还在讨论,分歧挺大,估计还要等)。

今年6,7月左右正式推出,中间可能会有一些新的提案进入stage4,到时会及时更新。

 

最后

以上就是体贴电话为你收集整理的ES2021新特性的全部内容,希望文章能够帮你解决ES2021新特性所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(50)

评论列表共有 0 条评论

立即
投稿
返回
顶部