众所周知,JavaScript中的sort()方法可对数组进行排序。
平时我们使用就是简单的执行一个sort()方法,但是其实这个方法是带有参数的。
语法为:arrayObject.sort(sortby);
其中,参数sortby,必须为函数!这点要注意,之前试过传值的方法一直都不奏效,后面才发现,只能传递一个参数。
未传参情况下的排序
当没有为该方法传参时,则默认对数组进行从大到小排序,排序的依据是数组中每个元素的首个字符的ASCII码,因此当你想要对数组[2,10,3]排序时,直接排序的结果为[10,2,3],因为在sort()的底层,比较时会自动为数组中的值进行toString()方法的转换,比较时比较的是字符。
传参情况下的排序
JS高程中介绍了传递比较函数的方法。1
2
3
4
5
6var 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
20sortBy: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()方法。`