一、問題的起因
偶然發現,在某些瀏覽器中顯示的圖表,日期排序混亂,如下圖。
逐步排查原因:
1、介面返回的資料沒有問題
2、大部分瀏覽器顯示沒有問題,只有chrome瀏覽器有問題
3、新版本的chrome瀏覽器沒有問題,出現問題的瀏覽器版本在70以下
二、真相只有乙個
考慮到谷歌瀏覽器在70版本後,對sort方法進行了調整,遂定位到問題的原因為sort排序的問題。為了更直觀的感受到不同版本瀏覽器中排序結果區別,在控制台中同時執行了以下排序操作。
var a = [10,5,40,25,1000,1];
a.sort(function());
根據sort方法的定義,以上**是將a陣列倒序顯示。在72.0版本中,執行結果如下
跟預期結果一致,沒有問題。然而在69.0版本中結果卻完全相反。
三、我的猜想
看到這個結果,我想知道chrome v8引擎,在進行排序演算法時,究竟做了什麼。
使用chrome版本 73.0.3683.86(正式版本)(64 位)來驗證,首先在控制台中對乙個陣列進行公升序排序。
var array = [4, 2, 5, 3, 1];
function compare(a, b)
array.sort(compare);
輸出結果
第一行輸出2 4,2-4<0,2移到4前面,陣列為[2,4,5,3,1]
第二行輸出5 2,5-2>0,陣列不變
第三行輸出5 4,5-4>0,陣列不變
根據前三行的輸出規律,接下來輸出依次應該是3 2,3 4,3 5,然而第四行卻直接輸出了3 4,這是因為演算法使用了二分法,提高比較效率,3-4<0,3移到4前面,陣列為[2,3,4,5,1]。
由於3<4,所以第五行直接比較3 2,3-2>0,陣列不變
第六行,依舊按照二分法,從1 4,開始比較,1-4<0,1移到4前面,陣列為[2,3,1,4,5]
同理,第七行結果為[2,1,3,4,5],第八行結果為[1,2,3,4,5],排序完畢。
四、驗證猜想
為了驗證上面推理的正確性,換乙個陣列驗證一遍,結果如下
第一行,5-10<0,5移到10前面,結果[5,10,40,25,1000,1]
第二行,40-5>0,陣列不變
第三行,40-10>0,陣列不變
第四行,採用二分法,直接比較25 10,25-10>0,陣列不變
第五行,由於25大於10,所以比較25 40,25-40<0,25移到40前面,結果[5,10,25,40,1000,1]
第六行,採用二分法,比較1000 25,1000-25>0,陣列不變
第七行,由於1000大於25,所以比較1000 40,1000-40>0,陣列不變
第八行,採用二分法,比較1 25,1-25<0,1移到25前面,結果[5,10,1,25,40,1000]
第九行,由於1<25,所以比較1 10,1-10<0,1移到10前面,結果[5,1,10,25,40,1000]
第十行,同理,結果為[1,5,10,25,40,1000],排序結束。與上述推理結果完全一致。
五、猜想的延伸
當排序的陣列很長的時候,每一次比較都會是一次二分,我後續使用長陣列驗證過了,由於陣列太長,這裡就不一行行來驗證了。若有錯誤和其他更好的猜想,歡迎指正和提出。
Js中sort排序規則
sort 方法用於對陣列的元素進行排序。arrayobject.sort sortby 引數 描述 sortby 可選。規定排序順序。必須是函式。對陣列的引用。請注意,陣列在原陣列上進行排序,不生成副本。如果呼叫該方法時沒有使用引數,將按字母順序對陣列中的元素進行排序,說得更精確點,是按照字元編碼的...
js中sort()方法的用法,引數以及排序原理
sort 方法用於對陣列的元素進行排序。語法 arrayobject.sort sortby 引數sortby可選。規定排序順序。必須是函式。注 如果呼叫該方法時沒有使用引數,將按字母順序對陣列中的元素進行排序,說得更精確點,是按照字元編碼的順序進行排序。要實現這一點,首先應把陣列的元素都轉換成字串...
JS中sort 方法的用法,引數以及排序原理
sort 方法用於對陣列的元素進行排序,並返回陣列。預設排序順序是根據字串unicode碼點。語法 arrayobject.sort sortby 引數sortby可選。規定排序順序。必須是函式。注 如果呼叫該方法時沒有使用引數,將按字母順序對陣列中的元素進行排序,說得更精確點,是按照字元編碼的順序...