不少人在使用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標準並未規定瀏覽器是否須要實現穩定的排序,這時,咱們須要藉助第三方庫或者本身實現排序。