符号……在JS语言中Rest和Spread场景都用到了。本周我们将结合JavaScript中的RestvsSpread语法来讨论两者的区别和一些陷阱。概述Spread...当用作Spread的意思时,作用是传播对象的属性:constobj={a:1,b:2,c:3,};constnewObj={...obj,};console.log(newObj);//{a:1,b:2,c:3}...这个符号很形象地表达了取出对象中的所有属性并平铺的意思。说到平铺,当Spread放在函数参数中时,也意味着将对象中的每个属性都取出来作为平铺参数:constarr=[1,2,3];constsum=(a,b,c)=>a+b+c;console.log(sum(...arr));//Outputs:6//^//sum(1,2,3)Rest...当用作Rest时,表示将多个Values集合为一个数组,如在函数定义中使用:constsum=(...args)=>{returnargs.reduce((acc,curr)=>acc+curr,0);//^//[1,2,3]};console.log(sum(1,2,3));//6当然也可以把其他变量放在...前面,这样...只聚合剩下的变量。...之后无法定义变量或...:constsum=(a,b,...restOfArguments)=>{returna+b+restOfArguments.reduce((acc,curr)=>acc+curr,0);//^^^//12[3,4,5]};console.log(sum(1,2,3,4,5));//15精读Rest处理SetandMapSetandMap可以通过数组方式赋初值:constmySet=newSet(["a","b","c"]);constmyMap=newMap([["a",1],["b",2],["c",3],]);当...符号用于Rest时,它可以解构为一个数组:[...mySet]//['a','b','c'][...myMap]//[['a',1],['b',2],['c',3]]特别说明,Map和Set只支持数组解构,不支持对象方式解构:{...mySet}//{}{...myMap}//{}但是对于普通数组,它同时支持数组和对象模式解构:constarr=['a','b','c'][...arr]//['a','b','c']{...arr}//{0:'a',1:'b',2:'c'}这是因为数组变量有潜在的下标,可以是转换为对象的key,但是MapSet没有下标,所以转换为对象时找不到key,所以不支持对象方式的解构。更具体的原因与对象的可迭代性有关。虽然Map和Set都支持迭代,但是如果你用forkeyof来测试,你会发现他们的key是undefined的。Spread会失去get()和set()Spread并不代表整个对象的完整复制,它可以复制对象属性定义中的瞬时值,例如:constobj={a:1,b:get(){return2}}constnewObj={...obj}newObj.b属性不再是get()方法,而是固定值2,在get()函数,或者当你想延迟加载代码时。原因是Spread毕竟不是在定义一个对象,更恰当的理解应该是“访问一个对象”,所以访问的结果就是执行了get()。Rest会跳过不可枚举的属性consterr=newError('error'){...error}//{}Error有两个不可枚举的属性message和stack,所以不会被Rest收集。这种场景可以使用其他方法,比如直接访问error.message。总结一下...用在赋值位置就是Spread,用在参数集合位置就是Rest。同时由于语法写起来很简单,有一些默认逻辑要注意不要掉坑里。比如对象属性的getter会默认执行。跳过不可枚举的属性等。讨论地址为:Jingdu《Rest vs Spread 语法》·Issue#447·dt-fe/weekly想参与讨论的请点这里,每周都有新话题,周末或周一发布。前端精读——帮你过滤靠谱的内容。关注前端精读微信公众号
