前端又要出新语法了。。
发布日期: 2023-04-26 13:09:45 来源: 程序员鱼皮

大家好,我是鱼皮。不得不说,前端更新迭代地太快了,不止是各种各样的轮子、框架,JS 本身也在持续发布新语法。

这篇文章就分享下预计今年发布的 ECMAScript版本的一些新特性。大家可以当个收藏文~


【资料图】

数组查找

在数组中查找元素是非常见的需求,但是目前 ECMAScript只支持 indexOflastIndexOf两个数组查找方法。

如果我们想要查找满足条件的最后一个元素时,就需要使用 reverse方法:

constarray=[{value:1},{value:2},{value:3},{value:4}];array.find(n=>n.value%2===1);//{value:1}array.findIndex(n=>n.value%2===1);//0//使用reverse和find实现查找[...array].reverse().find(n=>n.value%2===1);//{value:3}array.length-1-[...array].reverse().findIndex(n=>n.value%2===1);//2

但是使用这种方法存在一些问题,如不必要的突变和复制,以及复杂的索引计算。

所以,为了解决这个问题引入了一项新的提案,目的是提供一种更清晰地表示查找操作的方法。还可以提高性能,避免不必要的开销。虽然性能提升不一定非常的显著,但在某些性能敏感的场景下可能会非常有用,比如 React渲染函数里面。

这个提案的核心功能就是在数组中通过条件函数从后往前查找元素。新的方法名为 {Array, %TypedArray%}.prototype.findLast{Array, %TypedArray%}.prototype.findLastIndex,它们的行为就类似于 Array.prototype.findArray.prototype.findIndex,但是是从后往前查找的。这样一来,就可以避免不必要的突变和复制,同时也可以减少索引计算的复杂度:

//使用新的findLast和findLastIndex实现查找array.findLast(n=>n.value%2===1);//{value:3}array.findLastIndex(n=>n.value%2===1);//2

Hashbang Grammar

Hashbang Grammar提案主要是为了规范在 CLI中执行 JS脚本的 shebangs的使用。

所谓 shebangs,就是在文件开头的一行,以 #!开头的注释,用来指定脚本的解释器。

举个例子,比如在 Unix/Linux系统中,我们可以在脚本的第一行写上:

#!/usr/bin/envnodeconsole.log("你好呀17");

这个注释的意思是,使用 Node.js作为解释器来运行这个脚本。

现有的 JS CLI脚本通常会去掉 hashbangs,然后再把剩下的代码传给 JS引擎去执行。Hashbang Grammar提案主要就是建议把去掉 hashbangs的工作移到引擎中去做,以此来统一和规范化操作的方式。

WeakMap 的 Symbols key

目前,WeakMaps仅允许使用普通对象作为 key,这是一种限制,主要是因为目标是拥有可以最终进行垃圾回收的唯一值。

SymbolECMAScript中唯一允许唯一值的原始类型。像使用 Symbol([description])表达式调用的时候产生的值只能通过访问它的原始输出来识别。任何其他相同的表达式都不会恢复最开始生产的原始值。

那么,使用 Symbol作为 key主要是因为下面两个好处吧。

第一个是使用 Symbol作为 WeakMapkey可以更清晰地表明它的键和映射项的角色关系,而不需要创建一个只用作键的新对象。

constweak=newWeakMap();constkey=Symbol(\"ref\");weak.set(key,\"HiHiHi17\");console.log(weak.get(key));

在之前的文章中我们讲过 ES 中有一个新的关于沙箱的提案 ShadowRealms

ShadowRealms方案会禁止访问一个对象的值。大多数虚拟化环境情况下,会在基于 Realms相关 API构建一个 Membranes系统,然后使用 WeakMaps连接引用。由于 Symbol值是原始值,仍然是可以访问的,在这个场景中是非常实用的:

constobjectLookup=newWeakMap();constotherRealm=newShadowRealm();constcoinFlip=otherRealm.evaluate(`(a,b)=>Math.random()>0.5?a:b;`);//later...leta={name:"alice"};letb={name:"bob"};letsymbolA=Symbol();letsymbolB=Symbol();objectLookup.set(symbolA,a);objectLookup.set(symbolB,b);a=b=null;//oktodropdirectobjectreferences//connectedidentitiespreservedasthesymbolsround-trippedthroughtheotherrealmletchosen=objectLookup.get(coinFlip(symbolA,symbolB));assert(["alice","bob"].includes(chosen.name));

Change Array by copy

为啥这个提案叫 Change Array by copy呢?字面意思就是从副本里改变数组。

这就要说起数组的破坏性和非破坏性方法了:

有些数组的方法我们在调用的时候不会改变原始的数组,我们称它们为非破坏性方法,比如我们经常用到的 filter、some、map、find等方法,斗是不会改变原数组的:

但是,另外有一些方法是会改变原数组本身的,比如:sort、reverse、splice等方法。

可以看到,原数组和排序后得到的新数组是一样的,说明这个方法改变了原数组。很多时候我们想用这些方法,但是又不想改变原数组,我们可能会先创建一个副本,比如下面这些操作:

constsorted1=array1.slice().sort();constsorted2=[...array1].sort();constsorted3=Array.from(array1).sort();

几个数组的新方法,就是用来解决这样的问题的。

toSorted()

.toSorted().sort()的非破坏性版本:

constarray=["c","o","n","a","r","d","l","i"];constresult=array.toSorted();console.log(result);//["a","c","d","i","l","n","o","r"]console.log(array);//["c","o","n","a","r","d","l","i"]

下面是个简单的 polyfill

if(!Array.prototype.toSorted){Array.prototype.toSorted=function(compareFn){returnthis.slice().sort(compareFn);};}

toReversed()

.toReversed().reverse()的非破坏性版本:

constarray=["c","o","n","a","r","d","l","i"];constresult=array.toReversed();console.log(result);//["i","l","d","r","a","n","o","c"]console.log(array);//["c","o","n","a","r","d","l","i"]

下面是个简单的 polyfill

if(!Array.prototype.toReversed){Array.prototype.toReversed=function(){returnthis.slice().reverse();};}

with()

with()是对数组的某个元素赋值操作的非破坏性版本,比如下面的操作:

array[index]=value

如果我们只是想得到一个新数组,又不想改变原数组,可以这样用:

constarray=["c","o","n","a","r","d","l","i"];constresult=array.with(0,"ConardLi")console.log(result);//["ConardLi","o","n","a","r","d","l","i"];console.log(array);//["c","o","n","a","r","d","l","i"]

下面是个简单的 polyfill

if(!Array.prototype.with){Array.prototype.with=function(index,value){constcopy=this.slice();copy[index]=value;returncopy;};}

toSpliced()

.splice(start, deleteCount, ...items)方法比其他几个破坏性方法更复杂点:

它从 start 开始删除 deleteCount 个元素 ; 然后把 items 插入到被删除的位置; 最后返回已删除的元素。
constarray=[1,2,3,4,5,6];constresult=array.splice(1,2,0);console.log(result);//[2,3]console.log(array);//[1,0,4,5,6]

.tospliced().splice()的非破坏性版本,它会返回原数组变更后的版本,因此我们拿不到被删除的元素:

constarray=[1,2,3,4,5,6];constresult=array.tospliced(1,2,0);console.log(result);//[1,0,4,5,6]console.log(array);//[1,2,3,4,5,6]

下面是个简单的 polyfill

if(!Array.prototype.toSpliced){Array.prototype.toSpliced=function(start,deleteCount,...items){constcopy=this.slice();copy.splice(start,deleteCount,...items);returncopy;};}

最后

大家感觉哪个最有用?

往期推荐

关键词:

相关文章

  • 前端又要出新语法了。。

  • 环球滚动:4月26日国内DOP企业报价回落

  • 洲际酒店集团高歌猛进,一举签约24家酒店

  • 【世界快播报】高原深山有“好物” 阿坝黑水养出好“钱景”

  • 中超综合|青岛海牛大胜北京国安 武汉三镇绝杀梅州客家|快看

  • 什么是Zigbee?无线网络技术解释

  • 引导农民多种粮种好粮

  • 4月26日河北中昌化肥硫酸铵价格动态

  • 4月26日兖矿国泰醋酸乙酯价格报稳-天天要闻

  • 4月26日尔泰实业黄磷最新报价|每日讯息

  • “股王”一季度成绩单超棒:净利超200亿!|世界热推荐

  • 短讯!一季度软件和信息技术服务业保持两位数增长 江苏企业数量

  • “科技赋能 价值共生” 2023全国汽车行业数字化高质量发展峰

  • 焦点快看:第四届全国老年人体育健身大会在泸州开幕

  • 宜宾翠屏区:“线上+线下” 搭建“一站式”零工就业服务桥_世界

  • 绵阳平武:“五联五促”建平安边际 共谋共享护安全和谐

  • 中国国际经济交流中心副理事长、国家发改委原副主任杜鹰一行赴德

  • 全球简讯:2023武汉五一劳动节景区免费优惠政策汇总

  • 4月26日 11:04分 德新科技(603032)股价快速拉升

  • 4月26日湖南地区锑锭市场价格 环球实时

热点图集