基于原生JS封装数组原型上的sort方法
基于原生JS封装数组原型上的sort方法
最近学习了数组的原型上内置方法的封装,加强了用原生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;
};
实验结果
无参(参数非函数)对纯数字数组的排序

带参对纯数字数组的排序(升序)

带参对纯数字数组的排序(降序)

无参(参数非函数)对纯字母字符串数组的排序

带参(参数是函数)对纯字母字符串数组的排序(升序)

带参(参数是函数)对纯字母字符串数组的排序(降序)

无参(参数非函数)对纯字母字符串、数字字母组合字符串、纯数字字符串组合的排序

带参(参数是函数)对纯字母字符串、纯数字、数字字母字符串、纯数字字符串等的组合排序结果(升序)

带参(参数是函数)对纯字母字符串、纯数字、数字字母字符串、纯数字字符串等的组合排序结果(降序)

无参(参数非函数)对纯字母字符串、纯数字、数字字母字符串、纯数字字符串等的组合排序结果

带参(参数是函数)对纯字母字符串、纯数字、数字字母字符串、纯数字字符串等的组合排序结果(升序)

带参(参数是函数)对纯字母字符串、纯数字、数字字母字符串、纯数字字符串等的组合排序结果(降序)

无参(参数非函数)对数组、纯字母字符串、纯数字、数字字母字符串、纯数字字符串等的排序

带参(参数是函数)对数组、纯字母字符串、纯数字、数字字母字符串、纯数字字符串等的排序(升序)

带参(参数是函数)对数组、纯字母字符串、纯数字、数字字母字符串、纯数字字符串等的排序(降序)

带参(参数是函数)对纯数组的排序(升序)

带参(参数是函数)对纯数组的排序(降序)

带参(参数是函数)对纯对象的排序(升序)

带参(参数是函数)对纯对象的排序(降序)

基于原生JS封装数组原型上的sort方法的更多相关文章
- 用jQuery基于原生js封装的轮播
我发现轮播在很多网站里面都用到过,一个绚丽的轮播可以为网页增色不少,最近闲来无事,也用原生js封装了一个轮播,可能不像网上的插件那么炫,但是也有用心去做.主要用了闭包的思想.需要传递的参数有:图片地址 ...
- 基于原生js的图片延迟加载
当页面图片比较多的时候,我们通常会做一个延迟加载,避免页面打开时一下子的请求数太多,加载过慢影响用户体验. 如果项目用了jquery框架,则可以直接用 jquery.lazyload.可在jquery ...
- 基于原生js的返回顶部组件,兼容主流浏览器
基于原生js的返回顶部插件,兼容IE8及以上.FF.chrome等主流浏览器. js文件中封装了getScrollTop()和changeScrollTop()函数分别用于获取滚动条滚动的高度和修改滚 ...
- 原生JS封装创建多级菜单函数
手写一个使用原生JS封装的多级菜单的函数,满足以下几点需求. 子类层级不确定,可根据数据自动生成多级菜单. 操作便捷,只需传入一个HTML标签. 缺点: 需要满足特定的数据结构 废话不多说,展示代码. ...
- 用原生js封装轮播图
原生js封装轮播图 对于初学js的同学来说,轮播图还是一个难点,尤其是原生js封装轮播图代码,下面是我之前做的一个轮播图项目中封装好的一些代码,有需要的同学可以看一下,有什么不懂的可以看注释,注释看不 ...
- 使用原生JS封装一个动画函数
最近一直在忙项目,很少有时间回顾之前的知识,今天刚好要做一个轮播,因为对兼容性有一定的要求,使用了各种插件和库中的轮播,效果都不是很理想,一怒之下,使用原生JS封装了一个轮播组件,其中重要的功能就是一 ...
- 原生JS封装Ajax插件(同域&&jsonp跨域)
抛出一个问题,其实所谓的熟悉原生JS,怎样的程度才是熟悉呢? 最近都在做原生JS熟悉的练习... 用原生Js封装了一个Ajax插件,引入一般的项目,传传数据,感觉还是可行的...简单说说思路,如有不正 ...
- 原生JS封装简单动画效果
原生JS封装简单动画效果 一致使用各种插件,有时候对原生JS陌生了起来,所以决定封装一个简单动画效果,熟悉JS原生代码 function animate(obj, target,num){ if(ob ...
- 原生Js封装的弹出框-弹出窗口-页面居中-多状态可选
原生Js封装的弹出框-弹出窗口-页面居中-多状态可选 实现了一下功能: 1.title可自定义 可拖拽 2.width height可以自定义 3.背景遮罩和透明度可以自定义 4.可以自己编辑弹出 ...
随机推荐
- Windows(7)上不能启动MySQL服务(位于本地计算机上)错误1067 :进程意外终止
就这段时间,很多人在抱怨为什么自己的MySQL又打不开问题. 就“Windows(7)上不能启动MySQL服务(位于本地计算机上)错误1067 :进程意外终止”这个问题,我想到了几种方案解决: 一.首 ...
- windows7 端口查看以及杀死进程释放端口
1.调出命令窗口:开始---->运行---->cmd,或者是window+R组合键 2.输入命令:netstat -ano,列出所有端口的情况.在列表中我们观察被占用的端口,比如是4300 ...
- Hadoop学习---Hadoop的MapReduce的原理
MapReduce的原理 MapReduce的原理 NameNode:存放文件的元数据信息 DataNode:存放文件的具体内容 ResourceManager:资源管理,管理内存.CPU等 Node ...
- IM
一.IM技术概念 IM技术全称Instant Messaging,中文翻译"即时通讯",它是一种使人们能在网上识别在线用户并与他们实时交换消息的技术,是电子邮件发明以来迅速崛起的在 ...
- c++ 读取文本问题
c++文本操作有以下三个方法 ifstream,ofstream,fstream 读取文本常用的方法如下 std::ifstream input; input.open(".log" ...
- batik-all-1.7
处理highcharts导出图片出现中文乱码所用到的jar包
- jQuery 实现改变图片指定区域的颜色
javascript本身无法改变图片的颜色,不过我们可以通过一些技巧来实现一样的效果. 1.首先我们要知道图片哪些区域需要改变颜色,这里我们可以用执点地图的方法来弄 例1: <img src=& ...
- 【DP】:CF #319 (Div. 2) B. Modulo Sum
[题目链接]:http://codeforces.com/contest/577/problem/B [相似题目]:http://swjtuoj.cn/problem/2383/ [题意]:给出n个数 ...
- StringUtils工具类介绍
1 abbreviate方法缩写一段文字 StringUtils.abbreviate("abcdefghijklmno", -1, 10) = "abcdefg...& ...
- .net 基础(一)
方法 只需要考虑2个 东西 1. 方法的参数 2.方法的返回值 当参数的个数不确定的时候,可以采用可变参数params. params 数组的 个数,不确定.当传入的 参数为空的时候,可变参数的数组 ...