当前位置: 首页 > 科技观察

这些JS的新语法有些东西

时间:2023-03-19 21:09:35 科技观察

TC39的提议被作者跟进了,我把一些有意思的留了下来,今天讲一下。PS:该提案一共有五个阶段,直到第4阶段才会被包含在发布规范中,其他的只会有机会被包含。.at()这是一个不错的新语法。其他一些语言可以使用arr[-1]来获取数组末尾的元素,但这对JS来说是不可能的。因为[key]是为对象获取key对应的value。数组也是对象,对数组使用arr[-1]就是得到key为-1的值。由于上述原因,如果我们要获取最后一个元素,就必须写成arr[arr.length-1]。以后有了at方法,我们就可以用arr.at(-1)来获取最后一个元素了,同样适用于Array-like,String。//Polyfillfunctionat(n){//ToInteger()abstracttopn=Math.trunc(n)||0;//Allowegativeindexingfromtheendif(n<0)n+=this.length;//OOBaccessisguaranteedtoreturnundefinedif(n<0||n>=this.length)returnundefined;//Otherwise,thisisjustnormalpropertyaccessreturnthis[n];}顶层的awaitawait必须用async函数包裹。大家一定知道,这个限制让我们无法在全局范围内直接使用await,必须要wrapped。有了这个提议,大家可以直接在顶层写await,很方便的提议。目前,该提案已进入第四阶段,并将确定发布。另外,其实Chrome最近的更新已经支持这个功能了。image-20210620162451146Error原因这个语法主要是帮助我们方便的传递Error。一旦有很多地方可能出错,我们其实并不知道哪里出错了。如果我们想让外界清楚地知道上下文信息,我们需要封装下面的错误。asyncfunctiongetSolution(){constrawResource=awaitfetch('//domain/resource-a').catch(err=>{//Howtowraptheerrorproperly?//1.thrownewError('Downloadrawresourcefailed:'+err.message);//2.constwrapErr=newError('Downloadrawresourcefailed');//wrapErr.cause=err;//throwwrapErr;//3.classCustomErrorextendsError{//constructor(msg,cause){//super(msg);//this.cause=cause;//}////thrownewCustomError('Downloadrawresourcefailed',err);})constjobResult=doComputationalHeavyJob(rawResource);awaitfetch('//domain/upload',{method:'POST',body:jobResult});}awaitdoJob();//=>TypeError:Failedtofetch那么有了这个语法以后,我们可以这样来简化代码:asyncfunctiondoJob(){constrawResource=awaitfetch('//domain/resource-a').catch(err=>{thrownewError('Downloadrawresourcefailed',{cause:err});});constjobResult=doComputationalHeavyJob(rawResource);awaitfetch('//domain/upload',{method:'POST',body:jobResult}).catch(err=>{thrownewError('Uploadjobresultfailed',{cause:err});});}try{awaitdoJob();}catch(e){cconsole.log(e);console.log('Causedby',e.cause);}//Error:Uploadjobresultfailed//CausedbyTypeError:Failedtofetchpipelineoperator这个语法有很多star,有5k多,边也可以说明是流行的语法,不过应该要很久才会发布了。毕竟这个proposal是三四年前提出来的,现在还只是stage1。这个语法在其他函数式编程语言中其实很常见,主要是为了方便函数调用:letresult=exclaim(capitalize(doubleSay("你好")));result//=>"你好,你好!"letresult="hello"|>doubleSay|>capitalize|>exclaim;result//=>"Hello,hello!"这只是单个参数的用法。对其他用法感兴趣的读者可以自行阅读提案,其中涉及的内容比较多,估计也是进度缓慢的原因。新的数据结构:Records&Tuples的数据结构我觉得发布后会特别好用。一共有两个新的数据结构,我们可以通过#:1来声明。#{x:1,y:2}2.#[1,2,3,4]这个数据结构是不可变的,类似于immer或者immutable.js在React中引入用于性能优化,其中值只接受基本类型或同样不可变的数据类型。constproposal=#{id:1234,title:"Record&Tupleproposal",contents:`...`,//tuplesareprimitivetypessoyoucanputtheminrecords:keywords:#["ecma","tc39","proposal","re??cord","tuple"],};//访问keyslikeyouwithobjects!console.log(proposal.title);//记录&Tupleproposalconsole.log(proposal.keywords[1]);//tc39//Spreadlikeobjects!constproposal2=#{...proposal,title:"Stage2:Record&Tuple",};console.log(proposal2.title);//Stage2:Record&Tupleconsole.log(proposal2.keywords[1]);//tc39//ObjectfunctionsworkonRecords:console.log(Object.keys(proposal));//["contents","id","keywords","title"]最后,作者在上面列出了一些有趣的TC39提案。除了上述之外,还有许多其他建议。如果您有兴趣,可以在TC39中找到它们。