详解JS数组API方法重构( 二 )
<= index) return 0;if (arrNum < 0) return 0;if (~index+ 1 > arr.length) return 0;//如果索引为负 , 在这里转为正(从后往前)if (index< 0) {index= index+ arr.length;}//for循环遍历删除元素 , 后面的元素前移for (i = 0; i < arr.length - index; i++) {if (i < arrNum) delArr[i] = arr[index+ i];arr[index+ i] = arr[index+ arrNum + i];}//删除多余元素arr.length -= arrNum;//如果需要插入元素 , 则进行下面操作if (arguments[3]) {arr.length += arrArgumentsNum;//循环让元素后移for (i = 0; i < arrArgumentsNum; i++) {arr[arr.length - i - 1] = arr[arr.length - arrArgumentsNum - i - 1];}//添加对应元素for (i = 0; i < arrArgumentsNum; i++) {arr[index+ i] = arguments[i + 3];}}return delArr;}利用splice去重Array.prototype.distinct=function(){for(var i=0;iif(this.indexOf(this[i])!=i){this.splice(i,1);i--;}}return this;}var arr=[1,1,2,3,4,5,6,2,3,4,5,6,7,1,2,3,4,5,6];arr.distinct();//arr=[1, 2, 3, 4, 5, 6, 7]案例:1、去重(去掉重复的)第一种方法var arr=[1,2,3,4,1,2,3,2,1,1,3,7,7,2,1,6,1,2,4,5,1,2,3];var arr1=[]for(var i=0;ivar item=arr[i]var bool=truefor(var j=0;jif(arr1[j]===item){bool=falsebreak}}if(bool){arr1.push(item)}}console.log(arr1)第二种方法for(var i=0;ivar item=arr[i]for(var j=i+1;jif(item===arr[j]){arr.splice(j,1) //从 j 位置开始 , 删除 1 个元素j- -}}}console.log(arr)4 slice;按指定位置截取复制内容 , 只能从前向后截取 , 第二个参数可以不写 , 默认到尾部;包括开始的位置 , 不包括结束的位置arr.slice(从第几位开始(可以为负数 , 但是必须大于后面) , 到第几位结束)重构slice//第一种 , 比较绕function slices(array,start,end){var arr1=[];if(!array || !Array.isArray(array)) return arr1;if(end===undefined) end=array.length;if(start =.= undefined) start=0;//防止用户都没有填 , 返回默认值start=Number(start);end=Number(end);if(isNaN(start)) start=0;if(isNaN(end)) end=array.length;if(start<0) start=array.length+start;if(end<0) end=array.length+end;//当为负值时 , 从数组后面开始算for(var i=start;iarr1.push(array[i]);//将选中的元素添加到新数组里}return arr1; //返回新数组}//第二种,相对来说更好理解一点function slices(arr,startNum,endNum){if(startNum>endNum || startNum>arr.length) return;//如果不是从前向后或者初始值大于数组长度 , 直接返回var arr1=[];//为了返回新数组做准备if(endNum===undefined || endNum>arr.length) endNum=arr.length;if(startNum===undefined) startNum=0;//如果两个初始值都没有被定义 , 直接赋值为默认值if(endNum<0) endNum=arr.length+endNum;if(startNum<0) startNum=arr.length+startNum;//如果输入的初始值为负值 , 倒数开始计算if(startNum<0 iarr1.push(arr[i]);}//这个是当满足初始值为负 , 结束为正的情况而设 , 小编暂时也没有想出好点的方法}for(var i=startNum;iarr1.push(arr[i]);}//将截取范围的元素添加给arr1并且返回return arr1;}slice的应用 复制var arr=[1,2,3];var copies = arr.slice(0);arr.length=0;//arr数组删除所有元素console.log(copies);console.log(arr);5 indexOf和lastindexOf;查找find 返回数组中第一个符合条件的元素 , findIndex返回索引(两中比较少用)1)indexOf(查询元素 , 从什么位置开始) , 如果查到 , 返回该元素的下标 。 并且不会在继续查找 。 如果没有查到 , 则返回-1当查询中有数组或者对象的时候 , 因为引用地址不同 。 所以无法查到2)lastindexOf,和indexOf一样 , 只不过是从数组后面开始查找案例:1 、用indexOf去重var arr=[1,3,1,2,3,5,2,3,4,6];var arr1=[]for(var i=0;iif(arr1.indexOf(arr[i])===-1){arr1.push(arr[i])}}console.log(arr1)6 Array.from 将类数组转换成数组 , 拥有数组的方法Array.of 把参数合并成一个数组返回 , 如果参数为空 , 则返回一个空数组ES6中;arr=Array.from(类数组);ES5中;arr=Array.prototepy.slice.call(类数组)7数组的遍历;forEach和map , for循环 , for in1)forEach 遍历数组 , 没有返回值arr.forEach(function(item,index,arr){});重构forEachfunction forEachs(array,callBack){if(!array || !Array.isArray(array)) console.error("forEachs is not function");for(var i=0;icallBack(array[i],i,array)};// 遍历传入的数组 , 把数组的元素、下标、数组传入回调函数} //不返回任何东西 }2)map 遍历数组 , 返回和原数组长度相同的新数组 , 如果没有定义 , 直接为返回元素为undefinedarr.map(function(item,index,arr){});map的重组` function maps(array,callBack){if(!array || !Array.isArray(array)) console.error("maps is not function");var arr1=[];//为返回新数组做准备for(var i=0;iif(array[i]===undefined) continue; //遍历过程中遇到undefined,跳出去这一次循环 , 后面继续 , 所以用continue;arr1[i]=callBack(array[i],i,array);//新数组的元素是回调函数中返回的结果}for(var j=0;jreturn arr1[j]===undefined ? undefined : arr1;} //如果新数组元素是undefined,返回值undefined,如果不是 , 返回新数组}`3)for in 遍历数组 , index为下标 , arr[index]为属性值 for(index in arr){}以上方法会跳过空元素;4) for循环 for(i=0;i1、for in不会遍历空元素 , for会遍历空元素2、for in可以遍历到数组的属性 , for只能遍历数组所有下标 , 不能遍历属性属性包含字符和下标(数字)for in 循环和普通for循环的区别:1、在循环数组时for in 循环给循环变量赋值为 字符串类型 , for in循环必须把所有的元素要循环一遍 , 普通的for循环给循环变量赋值为 数字类型 , 普通的for的循环 , 可以控制循环哪些元素 。 更加灵活2、循环对象:for in循环可以循环对象普通for循环 , 没法直接循环对象 。 3、 用for in循环数组时 , 就是把数组当作了对象处理 , 下标就是键(键就是再其实啊 , 浏览器在处理数组时 , 会(可以)把它当作对象8排序:按顺序排列 从小到大 , 或者从大到小时间复杂度和空间复杂度O(1) O(n) O(n log n)时间复杂度 算法计算花费时间 花时间越少时间复杂度越小空间复杂度 算法计算需要花费堆栈空间(内存)越多代表空间复杂度越高在排序时 , sort()方法会调用每个数组项的 toString()转型方法 , 然后比较得到的字符串 , 以确定如何排序 。 即使数组中的每一项都是数值 ,sort()方法比较的也是字符串1)冒泡排序;function bubbleSort(arr){for(var i=0;ifor(var j=0;jif(arr[j]>arr[j+1]) arr[j]=[arr[j+1],arr[j+1]=arr[j]][0];// 如果前面一项大于后面一项 , 两者交换}}return arr;}2)选择排序;function choiceSort(arr){for(var i=0;ifor(var j=i,minIndex=i;j//设定一个最小的下标用来比较if(arr[minIndex]>arr[j+1]) minIndex=j+1;// arr[i]>arr[j+1]的话就一直是arr[1]这个值在比较了 , 而我们希望遍历到数组最后 , 将最小的数的数组下标找到 , 所以arr[minIndex]}if(minIndex>i) arr[i] = [arr[minIndex],arr[minIndex]=arr[i]][0];//当mindex改变时 , 说明有最小下标 , 并将最小下标上的元素和当前元素交换}return arr;}3)str.charCodeAt()将字符串的第几项下标的元素转换成Unicode编码如;var str=“cbd012” 长度为6 , 从为第0项;str.charCodeAt(0);//将字符串的第0项转化为Unicode编码4)Math.random()-0.5;将数组随机乱序5)数组的排序方式 sort 只适用于数组arr.sort(function(后一项(a) , 前一项(b))){return a-b //从小到大return b-a //从大到小return Math.random()-0.5 //数组随机乱序 , 此时不需要填写参数}5)这种方法用于字符排序var arr=["d","e","b","a","c","h","j","i","k"];arr.sort(function(a,b){// return a.charCodeAt(0)-b.charCodeAt(0) //从小到大return b.charCodeAt(0)-a.charCodeAt(0); //从大到小})console.log(arr)9 some和every1)some 查找数组是否有满足条件的元素 , 如果有就是返回true , 不继续向后遍历 , 没有返回falsearr.some(function(item,index,arr){})重构somefunction somes(arr,callBack){// callBack就是回调函数for(var i=0;iif(callBack(arr[i],i,arr)) return true;//只要一个满足就返回true , 并且退出函数不再执行}return false;}2)every 查找数组中的条件每一个是否满足条件 。 有就返回true , 只要有一就返回false;重构everyfunction everys(arr,callBack){for(i=0;iif(!(callBack(arr[i],i,arr))) return false;//只要一个不满足就返回false}return true;}10 filter和reduce及reduceRight1)filter 将满足条件的元素返回一个新数组 , “过滤”功能 , 数组中的每一项运行给定函数 , 返回满足过滤条件组成的数组 。 arr.filter(function(item,index,arr){});重构filterfunction filters(array,callBack){var arr1=[];//为返回满足条件的元素返回新数组做准备for (var i=0;iif(array[i]===undefined) continue;if(callBack(array[i],i,array)) arr1.push(array[i]); //如果这里用arr1[i]=array[i]; 结果是[empty,2,empty,4......]}//这是因为回调函数返回的是false true的布尔值 , 不满足条件的时候会直接跳过这个时候的i,这样arr1的不满足数位就是empty,但是用push , 就能直接添加满足的元素 。 return arr1; //这个注释可以用来区分map和filter的区别,map返回的是赋值后的结果}2)reduce,遍历数组 , 会将上一次的value返回给下一次的valuereduceRight()则从数组的最后一项开始 , 向前遍历到第一项 。 arr.reduce(function(value,item,index,arr){} 初始值) , 如过初始值没有写的话 , 首先value会等于arr[0]遍历从第一项开始 , 如果给了初始值 , 则初始值等于value , 遍历从第0项开始重构reducefunction reduces(arr,callBack,value){//第一种 规规矩矩的 , 更不绕if(value=http://kandian.youth.cn/index/==undefined){value=arr[0];for(var i=1;ivalue=callBack(value,arr[i],i,arr);console.log(value);}}else{for(var j=0;jvalue=callBack(value,arr[j],j,arr)console.log(value)}}//第二种var i=0;if(value===undefined){i=1value=arr[0];}for(;ivalue=callBack(value,arr[i],i,arr)console.log(value)}return value;}案例1、累积相加数组元素求和var arr=[10,3,4,7,3,5,8,9];var sum=arr.reduce(function(value,item){return value+item})console.log(sum);2、希望求累积相加数组元素求和 , 在基数100的前提下 , 100就是初始值var arr=[10,3,4,7,3,5,8,9];var sum=arr.reduce(function(value,item){return value+item},100)console.log(sum)11 判断是不是数组 , 不能用typeof1)ES6中;Array.isArray(arr) , 是就返回true , 不是返回false2)typeOf(arr)//只能判断数组的引用类型3)Array.isArray()//ES5新增4)instanceof 返回Boolean值 ,只能判断对象类型 , 基本数据类型不能判断 , 浏览器都兼容语法:value instanceof 类arr instanceof Array//返回布尔值 true12 参数列表 argumentsarguments 伪数组;只能在函数中被调用 , 所有的列表(类数组 , 伪数组)都可以通过[下标]的方式调用 。 arguments是实参中的列表 , arguments.callee就是当前函数 , 如果该函数是回调执行的 , arguments.callee.caller就是回调执行当前函数外的函数注意:arguments//参数列表 有长度length 伪数组 , 无法调用数组的方法非严格模式中 , 如果形参改变了 。 里面的arguments[i]会随着改变严格模式中 , 形参即使改变了 , 但是里面的arguments[i]不会改变13 arr的方法reverse();数组元素倒序或者反转var arr = [13, 24, 51, 3];console.log(arr.reverse()); //[3, 51, 24, 13]console.log(arr); //[3, 51, 24, 13](原数组改变)14 entries/keys/values 都取/取键/取值var arr=['a', 'b', 'c']for(let key of arr.keys()){console.log(key)} //0,1,2for(let value of arr.values()){console.log(value)} //a,b,cfor(let [key, value] of arr.entries()){console.log([key,value])} //[0,'a'],[1,'b'],[2,'c']15 includes判断数组是否包含某项 , 返回true/false[1, 2, 3, 4, 5].includes(4) //true总结:就是敲敲敲哦 , 相对于ES6新出的方法来说封装其方法应该是对回调函数的理解 , 下周小编应该就是会和大家一起讨论讨论回调函数哦 。 不喜勿喷哦 。 现在小编还有一个彩蛋哦 。 下面是一道经常被问到的面试题 , 虽然看起来简单 , 但是不小心还是会出错的哦 , 先别看答案试试吧;_________________________面试题console.log(![]==[]);//true // !true==[] false==""console.log(![]==![]);//true // !true==!trueconsole.log(![]==false);//true //false==falseconsole.log([]==true);//false //""==true;console.log([]=="");//true // ""=="" false==falseconsole.log(0==![]);//true //false==!trueconsole.log(0==[]);//true //false==false
- 编程猫领衔,9家编程app测评一览详解
- 详解m3u8协议
- ICPC--1200:数组的距离时间限制&1201:众数问题
- Django实战016:django中使用redis详解
- YAPI接口文档部署教程 Ubuntu 16.04
- C++核心准则?:标准库array或vector好于C数组
- redis 数据类型详解 以及 redis适用场景场合
- 五种IO模型详解
- 安卓面试必备的JVM虚拟机制详解,看完之后简历上多一个技能
- 这样和妻子解释:Java动态代理机制详解(JDK和CGLIB
