并且每年,JavaScript都会更新以添加新特性和新标准。ES2020是今年发布的,ES2020(ES12)也有望在明年2021年年中发布。每年,新特性都会经历四个阶段,第四阶段是最后一个阶段。本文将介绍提案4中的相关新特性,这也意味着这些新特性将在很大程度上出现在下一个版本中。Prophet:String.prototype.replaceAll添加了replaceAllPromise.anyWeakRefs逻辑运算符和赋值表达式编号分隔符replaceAll看到replaceAll这个词,很容易想到replace。在JavaScript中,replace方法只能替换字符串中匹配到的第一个实例字符,不能进行全局的多匹配替换。唯一的办法就是通过正则表达式进行相关的规则匹配和替换,replaceAll返回一个全新的字符串,所有符合匹配规则的字符都会被替换,替换规则可以是字符串也可以是正则表达式。letstring='我喜欢前端,我喜欢前端男虾'//用replace匹配所有console.log(string.replace(/like/g,'love'))//'我喜欢前端,我喜欢前端男虾'//使用replaceAllletreplaceAllStr=string.replaceAll('like','love')控制台。log(replaceAllStr)//'Ilovefrontend,Ilovefrontendmaleshrimp'需要注意的是,replaceAll使用正则表达式时,如果不匹配全局(/g),replaceAll()会抛出异常letstring='Ilikefrontend,Ilikefrontendpublicshrimp'console.log(string.replaceAll(/like/,'love'))//TypeErrorPromise.any当Promise列表中任意一个promiseresolve成功时,返回第一个resolve的结果状态if所有的promise都被拒绝,并抛出异常表明所有的请求都失败了Promise.any([newPromise((resolve,reject)=>setTimeout(reject,500,'哦,我被拒绝了')),newPromise((resolve,reject)=>setTimeout(resolve,1000,'Oh,sheacceptedme')),newPromise((resolve,reject)=>setTimeout(resolve,2000,'Oh,sheacceptedme'))),])。then(value=>console.log(`Outputresult:${value}`)).catch(err=>console.log(err))//Output//Outputresult:Oops,sheacceptsme下一个案例Promise.any([Promise.reject('Error1'),Promise.reject('Error2'),承诺.reject('Error3')]).then(value=>console.log(`requestresult:${value}`)).catch(err=>console.log(err))//输出AggregateError:AllpromiseswererejectedPromise.Any和Promise.race非常容易混淆,所以一定要区分。一旦promise触发了resolve或者reject,Promise.race会直接返回state结果,不管成功或者失败。WeakRefs使用Wea??kRefs的Class类来创建对象。弱引用(对一个对象的弱引用是指当该对象应该被GC回收时,它不会阻止GC的回收行为)当我们通过(const,let,var)创建一个变量时,垃圾回收器GC永远不会从内存中删除变量,只要它的引用仍然可访问WeakRef对象包含对对象的弱引用。对象的弱引用不会阻止垃圾收集器GC恢复对该对象的引用,GC可以随时删除它。WeakRefs在很多情况下都很有用,例如使用Map对象实现需要大量内存的键值缓存。这种情况下,尽快释放键值对占用的内存是最方便的。目前,可以通过WeakMap()或WeakSet()使用Wea??kRefs。例如,我想跟踪特定对象调用特定方法的次数。如果超过1000次调用,会做相应的提示letmap=newMap()functiondoSomething(obj){。..}functionuseObject(obj){doSomething(obj)letcalled=map.get(obj)||0called++if(called>1000){console.log('当前调用已超过1000次,over')}map.set(obj,called)}可以实现我们上面的功能,但是会出现内存溢出,因为每个传递给doSomething函数的对象都是永久保存在map中的,不会被GC回收,所以我们可以使用WeakMapletwmap=newWeakMap()functiondoSomething(obj){...}functionuseObject(obj){doSomething(obj)letcalled=wmap.get(obj)||0called++if(called>1000){console.log('当前调用次数有已经超过1000次了,over')}wmap.set(obj,called)}因为是弱引用,所以WeakMap和WeakSet的键值对是不可枚举的。WeakSet类似于WeakMap,但是WeakSet中的每个对象每个对象只能出现一次,并且WeakSet中的所有对象都是唯一的letws=newWeakSet()letfoo={}letbar={}ws.add(foo)ws.add(bar)ws.has(foo)//truews.has(bar)//truews.delete(foo)//删除foo对象ws.has(foo)//false已经删除ws.has(bar)//仍然existsWeakSet与SetWeakSet相比有以下两点不同,它只能是对象的集合,不能是任何类型的任意值。WeakSet弱引用。集合中的对象引用是弱引用。如果没有其他对WeakSet对象的引用,它们将被GC回收。最后,WeakRef实例有一个方法deref,返回被引用的原始对象,如果原始对象被回收则返回undefinedconstcache=newMap();constsetValue=(key,obj)=>{cache.set(key,newWeakRef(obj));};constgetValue=(key)=>{constref=cache.get(key);if(ref){returnref.deref();}};constfibonacciCached=(number)=>{constcached=getValue(number);if(cached)returncached;constsum=calculateFibonacci(number);setValue(number,sum);returnsum;};缓存远程数据可能不是一个好主意,因为远程数据可能会意外地从内存中删除。在这种情况下,最好使用LRU缓存之类的东西。Logicaloperatorsandassignmentexpressions逻辑运算符和赋值表达式,新特性结合了逻辑运算符(&&、||、??)和赋值表达式,而JavaScript现有的复合赋值运算符是:运算符:+=-=*=/=%=**=按位运算符:&=^=|=按位运算符:<<=>>=>>>=现有运算符在这两种方式下都有效表达式可以这样理解:aop=b等价于:a=aopb逻辑运算符和其他复合赋值运算符的工作方式不同表达式:aop=b等价于:a=aop(a=b)a||=b//等价于aa=a||(a=b)a&&=b//等价于aa=a&&(a=b)a??=b//等价于aa=a??(a=b)为什么不再和之前的计算公式a=aopb,但是a=aop(a=b)。因为后者当且仅当a的值为false时才会计算赋值,所以只在需要的时候才进行赋值,而前者的表达式总是进行赋值操作??=可以用来补充/初始化缺失的属性constpages=[{title:'mainvenue',path:'/'},{path:'/other'},...]for(constpageofpages){page.title??='defaulttitle'}console.table(pages)//(index)titlepath//0"mainvenue""/"//1"defaulttitle""/other"总结:&&=:当LHS值存在时,将RHS变量赋值给LHS||=:当当LHS值不存在时,将RHS变量赋值给LHS??=:当LHS值为null或undefined时,将RHS变量赋值给LHS数字分隔符数字分隔符,可以在数字之间创建可视化分隔符,通过_使用下划线分隔数字,使数字更具可读性constmoney=1_000_000_000//相当于constmoney=1000000000consttotalFee=1000.12_34//相当于consttotalFee=1000.1234这个新的feature也支持使用constnumber=0o123_456//等。定价为constnumber=0o123456这个新特性方便读取数据,也可以让我们这些“工人”更容易识别“资产”。!!Phase4,这次引入所有新特性,意味着会在下一个版本出现,而phase3没有引入,因为不确定是否一定会在下一个版本出现。本文介绍的新特性可以在最新版本的谷歌浏览器中直接愉快的体验。
