13种让人爱不释手的JS传播运算符的写法一个点,比如下面这样:[...arr]其实就是这么用的,不过事情这么简单,我就不用写了他们在这里。分机话务员给我最大的印象就是相当方便。不过最近在写代码的时候,经常遇到需要使用扩展算子的场景,于是索性在网上找了一些资料,把平时常用的应用场景罗列出来,发现这个算子真的很强大,它有多强大?我们来看看下面的用法。1.字符串转数组字符串转数组最常见的方式是这样的:letstr='hello'letarr=str.split('')console.log(arr)//['h','e','l','l','o']使用扩展运算符后,可以这样:letstr='hello'letarr=[...str]console.log(arr)//['h','e','l','l','o']2.类数组转数组在JS中,有一种数据结构叫做NodeList,它和数组很像,也叫“类数组”。班级是什么?MDN是这样定义它的:“类数组:任何具有长度属性和多个索引属性的对象。什么是类数组?以下可以看作类数组:NodeList:document.querySelectorAll()返回的对象;HTMLCollection:document.getElementsByTagName()返回的对象;Arguments:函数中的参数对象;类数组中没有数组push、map等一些方法,所以往往需要将它们转换成数组,通常我们这样转换:letnodeList=document.querySelectorAll('div')console.log(nodeListinstanceofNodeList)//trueletarr=Array.apply(null,nodeList)console.log(arrinstanceofArray)//true//或letarr2=[].slice.call(nodeList)console.log(arr2instanceofArray)//true//或letarr3=Array.from(nodeList)console.log(arr3instanceofArray)//true和扩展运算符你可以这样做:letnodeList=document.querySelectorAll('div')letarr=[...nodeList]console.log(arrinstanceofArray)//真3。向数组添加项目在数组中添加几个项目通常是这样完成的:letarr=[5]//addarrfromthehead.unshift(1,2)console.log(arr)//[1,2,5]//从尾部添加arr。push(6,7)console.log(arr)//[1,2,5,6,7]//从任意位置添加arr.splice(2,0,3,4)console.log(arr)//[1,2,3,4,5,6,7]使用展开运算符后:letarr=[3,4]arr=[1,2,...arr,5,6]console.log(arr)//[1,2,3,4,5,6]4。复制数组和对象通常是复制一个数组,可以这样做:letarr=[1,3,5,7]letarr2=arr.concat()//或letarr3=arr。slice()arr[0]=2console.log(arr)//[2,3,5,7]console.log(arr2)//[1,3,5,7]console.log(arr3)//[1,3,5,7]但有了展开运算符,复制数组可以写得非常简单:letarr=[1,3,5,7]letarr2=[...arr]arr[0]=2console。log(arr2)//[1,3,5,7]同理,扩展运算符也可以按照复制对象的通常做法进行复制:letperson={name:'Bran',age:12}letp2=Object。assign({},person)person.age=20console.log(person)//{name:'Bran',age:20}console.log(p2)//{name:'Bran',age:12}With传播运算符,复制对象非常方便:letperson={name:'Bran',age:12}letp2={...person}person.age=20console.log(person)//{name:'Bran',age:20}console.log(p2)//{name:'Bran',age:12}//你甚至可以这样写let{...p3}=person"注意:扩展运算符只能深复制一层结构的对象,如果对象是两层结构,使用扩展操作符的复制就是浅拷贝。5.合并数组或对象数组通常是这样的:letarr1=[1,3,5]letarr2=[2,4,6]letarr3=arr1.concat(arr2)console.log(arr3)//[1,3,5,2,4,6]使用展开运算符后,可以写成这样:letarr1=[1,3,5]letarr2=[2,4,6]letarr3=[...arr1,...arr2]console.log(arr3)//[1,3,5,2,4,6]对了,除了合并数组,它还可以合并对象。通常合并对象的方式是:letp1={name:'Bran'}letp2={age:12}letp3=Object.assign({},p1,p2)console.log(p3)//{name:'Bran',age:12}使用扩展运算符合并对象:letp1={name:'Bran'}letp2={age:12}letp3={...p1,...p2}console.log(p3)//{name:'Bran',age:12}6.解构对象我们在给对象设置参数的时候经常会这样做:可以这样写,但其实下面的写法并不是扩展运算符🤣的写法,而是剩下的运算符的写法,虽然写完后看起来差不多,但是在操作对象上,它基本上可以认为是传播算子的相反操作。展开运算符用于将对象的属性展开为多个变量。rest运算符用于将多个参数压缩为一个变量。letperson={name:'Bran',age:12,sex:'male'}let{name,...reset}=personconsole.log(name)//'Bran'console.log(reset)//{age:12,性别:'男'}7。给对象添加属性给对象添加属性通常是这样的:letperson={name:'Bran'}person.age=12console.log(person)//{name:'Bran',age:12}使用扩展运算符添加对象的属性:letperson={name:'Bran'}person={...person,age:12}console.log(person)//{name:'Bran',age:12}关于使用扩展运算符为对象添加属性,这里有2个技巧:1.设置新对象的默认值://person对象的默认age属性值为12letperson={age:12,...{name:'Bran'}}console.log(person)//{age:12,name:'Bran'}2.重写对象属性letperson={name:'Bran',age:12}//person对象的age属性重写为20person={...person,age:20}console.log(person)//{姓名:'布兰',年龄:20}8。设置对象Getter设置对象Getter通常是这样完成的:letperson={name:'Bran'}Object.defineProperty(person,'age',{get(){return12},enumerable:true,configurable:true})安慰。log(person.age)//12使用扩展运算符,可以这样写:letperson={name:'Bran'}person={...person,getage(){return12}}console.log(person.年龄)//129。展开数组作为函数参数。如果我们有一个有多个参数的函数,但是当我们调用它的时候,发现入参是一个数组。通常的做法是这样的:letarr=[1,3,5]functionfn(a,b,c){}fn.apply(null,arr)使用扩展运算符,就简单多了:letarr=[1,3,5]functionfn(a,b,c){}fn(...arr)10.如果一个参数无穷大的函数有这样一个累加函数,它会加up所有传入的参数,常见的方式是将参数整合成一个数组,然后这样:functiondoSum(arr){returnarr.reduce((acc,cur)=>acc+cur)}console.log(doSum([1,3]))//4console.log(doSum([1,3,5]))//9如果参数不是数组,但是需要一个一个传递,也就是说函数必须支持无限制的参数,那么可能会这样做:]。片。call(arguments)//returnargs.reduce((acc,cur)=>acc+cur)}console.log(doSum(1,3))//4console.log(doSum(1,3,5))//9console.log(doSum(1,3,5,7))//16有了扩展运算符,就简单多了:functiondoSum(...arr){returnarr.reduce((acc,cur)=>acc+cur)}console.log(doSum(1,3))//4console.log(doSum(1,3,5))//9console.log(doSum(1,3,5,7))//1611.扩展函数的剩余参数有时一个函数需要传递很多参数。比如小程序页面(WePY)的onLoad生命周期函数中,可能有很多其他页面传递过来的参数,那么函数中需要传递一些参数。数据初始化工作,所以会显得很臃肿,不美观,例如:functioninit(a,b,x,y){//进行一系列初始化数据工作}使用扩展运算符后,我们可以按照业务解构参数并将应该在一个函数中初始化的工作拆分为多个。您可以这样做:functionother(x,y){}functioninit(a,b,...restConfig){//使用a和b参数进行操作//其余参数传给原函数returnother(...restConfig)}12.结合Math函数。例如,当需要求一个数组的最大值时,通常是这样进行的:letarr=[3,1,8,5,4]functionmax(arr){return[].concat(arr)。sort((a,b)=>b-a)}console.log(max(arr)[0])//8//或者arr.reduce((acc,cur)=>Math.max(acc,cur))//8//或Math.max.apply(null,arr)//8但使用扩展运算符后,可以更简洁地写出数组的最大值:letarr=[3,1,8,5,4]letmax=Math.max(...arr)console.log(max)//813。以new表示如果你想通过Date构造函数创建一个日期实例,你可以这样做:letarr=[2021,1,1]letdate=newDate([].toString.call(arr))console.log(date)//'MonFeb01202100:00:00GMT+0800(中国标准时间)'//或letdate2=new(Function.prototype.bind.apply(Date,[null].concat(arr)))console.log(date2)//'MonFeb01202100:00:00GMT+0800(ChinaStandardTime)'扩展运算符更简单:letarr=[2021,1,1]letdate=newDate(...arr)console.log(date)//'MonFeb01202100:00:00GMT+0800(ChinaStandardTime)'总结这个算子用起来真的很简单,但是在功能效率上不得不说非常强大,所以我们要做的就是记住什么时候去使用它,所以为了让大家更好的记住这13个使用场景,我特地做了一张图给大家记住,是不是很有粘性呢?以上只是列举了13种写法,我想作为这么强大的算子,使用场景一定要多一些。
