不少人在使用sort时,确定这样写过:javascript
[1, 2, 5, 40].sort() >> [1, 2, 40, 5]
显然结果是不符合指望的,为何会这样呢,咱们先来看下ECMAScript标准。java
可选参数: compareFunction数组
形式:function (a, b) {浏览器
// need return numberide
}编码
1 将须要比较的值转换为字符串;spa
2 按照UTF-16编码,升序排序。code
compareFunction(a, b) {blog
return < 0 // a排在b前面排序
return === 0 // a和b这次不交换位置
return > 0 // b在a前面
}
undefined、empty、null元素都移到数组最后,且不参与比较。
根据ECMAScript标准的定义,不传入compareFunction时,数组元素被看成字符串进行排序了,因此会出现不符合指望的结果。
1 ToBoject:
调用C++方法,将数组转换成Object;
2 ArrayNativeSort(C++)排序;
3 若是2失败,使用js的排序方法排序。
1 MergeSort:
使用自底向上的归并排序;
对于length <= 3的小数组,使用插入排序;
2 MoveHoles:
将数组中的空元素移动到数组末尾。
MergeSort:
length < 24,使用插入排序;
length >= 24,使用自底向上的归并排序,初始sz = 4,使用插入排序初始化,使数组局部有序。
1 TO_OBJECT:
调用C++方法,将数组转换成Object;
移动空元素至数组末尾;
2 若是未传入compareFunction,将compareFunction置为C++的SmiLexicographicCompare方法;
3 排序。
length <= 10,插入排序;
length > 10,快速排序和插入排序的混合排序。
1 toObject:
将数组转换成Object;
2 compact:
移动空元素至数组末尾;
3 排序
bucketSort(未传入compareFunction):
桶排序,使每一个桶大小 < 32;
每一个桶中使用归并排序。
mergeSort(已传入compareFunction):
自底向上的归并排序
使用sort给数字数组排序时,注意必须传入compareFunction
有时,咱们但愿数组中重复元素排序先后的相对位置不发生变化,咱们就须要使用稳定的排序,例如插入、归并排序;
可是,ECMAScript标准并未规定浏览器是否须要实现稳定的排序,这时,咱们须要借助第三方库或者本身实现排序。