时间:2021-07-01 10:21:17 帮助过:4人阅读
最近学习了数组的原型上内置方法的封装,加强了用原生JS封装方法的能力,也进一步理解数组方法封装的过程,实现的功能。虽然没有深入底层,了解源码。以下解法都是基于个人理解用纯原生JS实现的功能。如有不对的地方,可以评论告诉我哟
首先,我们先来看一下sort方法的作用、参数、以及方法的返回值,原有数组是否发生改变
sort方法主要用于数组的排序
参数分为两种:
一种:传的参数是函数、 (排序主要看函数的返回值)
另一种:传的不是函数、或者不传(只要传的不是函数就对原来排序过程不产生影响)
方法的返回值是原来数组排序后的数组
原来数组发生改变,是排序后的数组
其次,我们来看一下sort方法要处理的各种情况之间的比较
情况1:
无参实现对字符串数组的排序情况2:
无参实现对number类型的数组进行排序情况3:
无参实现对字符串、number等混合类型的数组的排序情况4:
带参实现对number类型的数值数据排序情况5:
带参sort()对简单对象List的自定义属性排序情况6:
带参实现对字符串、number混合类型的数组的排序
sort方法对参数的处理:
情况1:如果参数不是函数,则不影响原来排序过程
情况2:如果参数是函数,则根据回调函数中的返回值进行排序。如果返回值大于0,则交换位置;如果返回值小于0,则不交换位置
如果返回值不是一个数字,则不交换位置
基于以上情况的讨论,sort方法实现的核心原理如下:
核心原理:不带参(以及带的参数不是函数)的情况下:默认升序排列
不带参的情况下,直接转字符串,逐个比较ASCII码的值
只要有一个是对象{}就不交换
带参数为函数的情况下:
根据函数的返回值进行比较;如果函数返回值大于0;则交换位置
实现代码如下:
Array.prototype.mySort = function(fn){ if(Object.prototype.toString.call(fn)==='[object Function]'){ //如果传进来参数的是函数 for(var i = 0;i<this.length-1;i++){ //遍历数组,将前后两项作为实参传给fn if(fn.call(this,this[i],this[i+1])>0){ //如果fn执行之后的返回值大于0.就调用swap方法交换位置 var a = this[i],b=this[i+1]; this[i] = swap(a,b).a; this[i+1] = swap(a,b).b; //交换之后,如果当前项不是第一项,则当前项(索引为i的项)继续跟前面的项进行比较 if(i>0){ for(var j = i-1;j>=0;j--){ if(fn.call(this,this[j],this[j+1])>0){ var a = this[j],b=this[j+1]; this[j] = swap(a,b).a; this[j+1] = swap(a,b).b; } } } } } }else{ //如果不是函数,则按正常排序 //遍历数组,将前后两项进行比较 for(var i = 0;i<this.length-1;i++){ var cur = this[i];//当前项 var next = this[i+1];//下一项 if(comASCII(cur,next)){ //当返回true的时候交换,并且交换完成之后,当前项继续往前比较 this[i] = swap(cur,next).a; this[i+1] = swap(cur,next).b; //当前项继续向前比较 if(i>0){ for(var k = i-1;k>=0;k--){ var cur = this[k]; var next = this[k+1]; if(comASCII(cur,next)){ this[k] = swap(cur,next).a; this[k+1] = swap(cur,next).b; } } } } } } //封装一个交换位置的函数 function swap(a,b){ return { a:b, b:a } } //如果不传参的情况下比较ASCII码 function comASCII(cur,next){ //全部转换为字符串、逐项比较ASCII码 cur = cur.toString(); next = next.toString(); //取长度最大值 var len = cur.length>next.length?next.length:cur.length; //当前后两项都不是不是{}类型的数据时,进行比较 if(cur!=='[object Object]'&&next!=='[object Object]'){ for(var j = 0;j<len;j++){ if(!isNaN(cur.charCodeAt(j))&&!isNaN(next.charCodeAt(j))){ //如果二者的ASCII码都是有效数字 if(cur.charCodeAt(j)>next.charCodeAt(j)){ //如果前一项比后一项当前的ASCII码大,则返回true,交换位置 return true; }else if(cur.charCodeAt(j)==next.charCodeAt(j)){ //如果相等直接进入下一轮循环 continue; }else{ //前项比后项小,直接返回false return false; } } } if(!isNaN(cur.charCodeAt(len))&&isNaN(next.charCodeAt(len))&&(cur.charCodeAt(len-1)==next.charCodeAt(len-1))){ //比较完之后,如果前一项ASCII还是有效数字,说明前项比后项大,交换 return true; } } //如果上述条件不满足,则不交换 return false; } //返回当前数组 return this; };
实验结果
相关推荐:
对Angular 6中滚动列表组件的封装的分析
以上就是JS封装数组原型:sort方法的使用介绍的详细内容,更多请关注Gxl网其它相关文章!