当前位置: 首页 > Web前端 > HTML5

es6中常用的数组操作和技巧总结

时间:2023-04-06 00:01:43 HTML5

定义一个数组constarray=[1,2,3];或者constarray=newArray();数组[0]='1';推荐使用第一种形式定义数组,new形式定义大量数组会比较耗时。new关键字的使用,除了需要实例化一个对象,或者极少数需要延迟加载数据的情况,基本上不需要使用new关键字。在Javascript中分配大量新变量地址是一项缓慢的操作,为了提高效率,您应该始终使用对象表示法。  在另一个搜索结果中,有这样一句话:“很简单,Array()是一个对象,[]是一个数据原型。使用newArray()系统,每次都会生成一个新的对象(每次a浏览器生成一个对象,它会消耗资源来构造它的属性和方法),它的子集是[];个人推荐使用[],效率高。浏览器对CPU的要求很高,所以往往需要技巧。比如把数字转成字符只要a=a+'';比用String效率高很多。检测数组Array.isArray([]);//trueArray.isArray(undefined);//false;orarrayinstanceofArray;//true检测对象的原型链是指向构造函数的原型对象还是array.constructor===Array;//true绝招:if(!Array.isArray){Array.isArray=function(arg){returnObject.prototype.toString.call(arg)==='[objectArray]';};}注:typeof[];//"object"不能用这个方法检查!!!常用方法1.array.concat(array1,array2,...arrayN);合并多个数组,返回合并后的新数组,原数组不变。constarray=[1,2].concat(['a','b'],['name']);//[1,2,"a","b","name"]2.array.every(回调[,thisArg]);检查数组中的每个元素是否都通过了回调测试,全部通过则返回true,否则返回false。//回调定义如下:element:当前元素值;index:当前元素下标;array:当前数组functioncallback(element,index,array){//回调函数必须返回true或false以判断每个是否通过测试returntrue||false;}3.array.filter(callback[,thisArg]);返回一个包含所有通过回调函数测试的元素的新数组。//回调定义如下,三个参数:element:当前元素值;index:当前元素下标;array:当前数组functioncallback(element,index,array){//回调函数必须返回true或false,返回true保留该元素,false不保留。返回真||假;}常量过滤=[1,2,3]。过滤器(元素=>元素>1);//过滤:[2,3];4.数组。查找(回调[,thisArg]);返回第一个通过回调函数测试的元素,否则返回undefined,回调函数的定义同上。constfound=[1,2,3].find(element=>element>1);//found:2如果需要查找元素的位置或者元素是否存在于数组中,使用Array.prototype。indexOf()或Array.prototype.includes()。5.array.findIndex(回调[,thisArg]);返回第一个通过回调函数测试的元素的索引,否则返回-1,回调函数定义同上。constfindIndex=[1,2,3].findIndex(element=>element>1);//findIndex:16.array.includes(searchElement,fromIndex);includes()方法用于判断一个数组是否包含指定值,返回true或false。searchElement:要搜索的元素;fromIndex:开始搜索的索引位置。[1,2,3].includes(2,2);//false7.array.indexOf(searchElement[,fromIndex=0]);返回数组中可以找到给定元素的第一个索引,如果不存在,则返回-1。searchElement:要搜索的元素;fromIndex:开始搜索的索引位置。[2,9,7,8,9].indexOf(9);//18.array.join(separator=',');将数组中的元素通过分隔符连接成一个字符串,返回字符串,分隔符默认为“,”。[1,2,3].join(';');//"1;2;3"9.array.map(callback[,thisArg]);返回一个新数组,新数组中的每个元素都是调用回调函数后返回的结果。注意:如果没有返回值,新数组会插入一个未定义的值。由于array.map没有过滤的功能,当array调用map函数时,如果不是将array中的所有数据都返回,必须先过滤,再map,也就是调用map的时候,它必须对数组元素中的每个数据都是有效的。constmapped=[{name:'aa',age:18},{name:'bb',age:20}].map(item=>item.name+'c');//映射:['aac','英国广播公司'];10.array.pop()和array.shift();pop是从数组中删除最后一个元素并返回最后一个元素的值,删除原数组的最后一个元素。当数组为空时返回undefined。[1,2,3].pop();//3shift删除数组首元素返回首元素,原数组首元素被删除。空数组返回未定义。constshifted=['one','two','three'].shift();//shifted:'one'11.array.push(element1,element2,....elementN)andarray.unshift(element1,元素2,...元素N);push向数组末尾添加一个或多个元素,并返回新数组的长度;unshift将一个或多个元素添加到数组的开头并返回新数组的长度。唯一的区别是插入的位置。constarr=[1,2,3];constlength=arr.push(4,5);//arr:[1,2,3,4,5];length:5push和unshift方法是通用的,通过call()或apply()方法调用可以完成合并两个数组的操作。constvegetables=['防风草','马铃薯'];constmoreVegs=['celery','beetroot'];//将第二个数组合并到第一个数组中//相当于vegetables.push('celery','beetroot');Array.prototype.push.apply(vegetables,moreVegs);或[].push.apply(vegetables,moreVegs);//蔬菜:['parsnip','potato','celery','beetroot']12.array.reduce(callback[,initialValue]);对数组中的每个元素(从左到右)执行回调函数累加,将其缩减为单个值。consttotal=[0,1,2,3].reduce((sum,value)=>{returnsum+value;},0);//总数是6constflattened=[[0,1],[2,3],[4,5]].reduce((a,b)=>{returna.concat(b);},[]);//扁平化为[0,1,2,3,4,5]//initialValue累加器初始值,回调函数定义:functioncallback(accumulator,currentValue,currentIndex,array){}accumulator表示累加器的值,初始化时,如果initialValue有值,则累加器的初始值为initialValue,整个循环从第一个元素开始;如果initialValue没有值,则累加器初始化为数组第一个元素的值,currentValue为数组第二个元素的值,整个循环从第二个元素开始。initialValue的数据类型可以是任意类型,不需要和原数组中的元素值类型保持一致。constnewArray=[{name:'aa',age:1},{name:'bb',age:2},{name:'cc',age:3}].reduce((arr,element)=>{if(element.age>=2){arr.push(element.name);}returnarr;//必须有return,因为return的返回值会赋给新的累加器,否则就是return的值累加器将是未定义的。},[]);//newArray是["bb","cc"];相当于上面的代码:constnewArray=[{name:'aa',age:1},{name:'bb',age:2},{name:'cc',age:3}].filter(element=>element.age>=2).map(item=>item.name);//newArrayis["bb","cc"];对于reduce的特殊使用,其实类似于省略了一个变量初始化步骤,然后通过每次回调返回修改变量,最后返回最终的变量值,类似于一个变量声明+一个forEach执行的过程。constnewArray=[];[{name:'aa',age:1},{name:'bb',age:2},{name:'cc',age:3}].forEach(item=>{如果(item.age>=2){newArray.push(item.name);}});13.array.reverse();反转数组中元素的位置。['one','two','three'].reverse();//['three','two','one'],原数组反转14.array.slice(begin,end)returnsa新数组包含从原数组索引位置开始到结束(不包括结束)的所有元素。constnewArray=['zero','one','two','three'].slice(1,3);//newArray:['one','two'];15.array.some(回调[,thisArg]);判断数组中是否包含可以通过回调测试的元素。与every不同的是,只要某个元素通过测试,就会返回true。回调的定义同上。[2,5,8,1,4].some(item=>item>6);//true16.array.sort([compareFunction]);对数组中的元素进行排序,当compareFunction不存在时,对元素进行排序转换为字符串的字符的Unicode位置进行排序,慎用!使用时请加入compareFunction函数,排序不稳定。[1,8,5].sort((a,b)=>{returna-b;//从小到大排序});//[1,5,8]17.array.splice(start[,deleteCount,item1,item2,...]);通过删除现有元素和/或添加新元素来更改数组的内容。start:指定修改的起始位置;deleteCount:从起始位置开始删除的元素个数;item...:要添加到数组中的元素,从起始位置开始。返回值是由删除的元素组成的数组。如果只删除了一个元素,则返回一个只包含一个元素的数组。如果没有删除任何元素,则返回一个空数组。如果deleteCount大于start后的元素总数,则start后的所有元素都将被删除(包括起始位)。constmyFish=['天使','小丑','普通话','鲟鱼'];constdeleted=myFish.splice(2,0,'drum');//在索引2处插入'drum'//myFish变成["angel","clown","drum","mandarin","sturgeon"],删除的是[]summarypush,shift,pop,unshift,reverse,sort、splice方法会对原数组进行修改,其他数组操作方法只是返回值不同,对原数组没有影响,即原数组保持不变。总结在查看vue代码的时候,发现vue教程中Array.apply(null,{length:20})的用法。apply一直认为第二个参数只能是类数组,比如[]或者Arguments。理解之后,我发现{length:20}也是类数组。具有length属性的obj在apply函数中被视为类数组。可以理解这里的{length:20}默认会被当做一个数组。下图中的切片操作是只能对数组对象进行的操作,所以这里是数组。看代码,apply生成的数组初始化为undefined,即生成一个长度为5的数组,数组的每个元素都初始化为undefined。调用Array(5)和newArray(5)的效果是一样的。官方网站解释说,在不使用new运算符的情况下将构造函数作为函数调用时,其行为与使用new运算符调用时的行为完全相同。他们也生成了一个长度为5的数组,但它是一个空数组,并且数组中的每个元素都没有被初始化。你为什么这样写?map函数不会遍历数组中未初始化或删除的元素(也有forEach和reduce方法具有相同的限制)。Array.apply(null,{length:5})用于初始化一个长度为5的数组,每一项的初始值未定义。render(createElement){returncreateElement('div',//这里apply的第一个对象为null,当调用的函数不需要这个对象时,可以传null,在es5之前浏览器会将null表示的this指向window.es5之后,浏览器不再将this指向window,这里传null是因为Array构造函数会重新创建this,不需要传入这个对象Array.apply(null,{length:20})。map(function(){//这里如果使用Array(2),map的回调函数不会执行returncreateElement('p','hi')}))}