JavaScipt中sort()方法的底层原理及妙用

众所周知,JavaScript中的sort()方法可对数组进行排序。
平时我们使用就是简单的执行一个sort()方法,但是其实这个方法是带有参数的。
语法为:arrayObject.sort(sortby);
其中,参数sortby,必须为函数!这点要注意,之前试过传值的方法一直都不奏效,后面才发现,只能传递一个参数。

未传参情况下的排序

当没有为该方法传参时,则默认对数组进行从大到小排序,排序的依据是数组中每个元素的首个字符的ASCII码,因此当你想要对数组[2,10,3]排序时,直接排序的结果为[10,2,3],因为在sort()的底层,比较时会自动为数组中的值进行toString()方法的转换,比较时比较的是字符。

传参情况下的排序

JS高程中介绍了传递比较函数的方法。

1
2
3
4
5
6
var a = [10,3,12];
var line = function(a,b){
return b -a;
}
a.sort(line)
console.log(a) //3,10,12

但是有个问题,这个数东西就只能针对数组额,但是如果我想要对数组对象进行排序呢?
其实方法类似,万变不离其宗。如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
 var arr = [
{name: "aaa", age: 0},
{name: "bbb", age: 18},
{name: "ccc", age: 8}
];
function compare(property){
return function(a,b){
var value1 = a[property]; //获取a的
var value2 = b[property];
return value1 - value2;
}
}
console.log(arr.sort(compare('age')));

逆向排序

那么问题来了,如果都是从小到大排序,那就不好玩了,能不能有办法在不使用reverse()方法的情况下,实现增加一个参数,来决定他们是从大到小排序,还是从小到大排序呢?
当然问题还是有解决方案的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
sortBy:function(attr,rev){
if(rev == undefined){
rev = 1; //当未传递参数时,默认为从小到大排序,即undefined时,为1
}else{
rev = (rev)? 1 : -1;
}
return function(a,b){
a = a[attr]
b = b[attr]
if(a < b){
return rev * -1;
} else if(a = b){
return 0;
} else {
return 1;
}
}
}

someArray.sort(sortBy("number",false));

底层原理

以上是研究出的部分结果,但是对sort()的底层排序机制,还是不太理解,到底是用的冒泡排序,还是堆排序,还是更牛逼的高级算法?这就不得而知了,这里引用一下segmenfault上大神们的解释:
不同的浏览器,对sort()方法的实现机制是不同的。
Mozilla、Firefox这两个浏览器是使用的归并排序方法。使用V8引擎,对数组长度小于等于22的用插入排序,其他的使用快速排序。
webkit这个浏览器底层使用了C++库中的qsort()方法。
`

文章目录
  1. 1. 未传参情况下的排序
  2. 2. 传参情况下的排序
  3. 3. 逆向排序
  4. 4. 底层原理
|