前幾天在某公司面試的時候被問到關於這個方法的默認值的問題(然而面試官跟我說的實際上是錯的,當場我還不夠底氣去反駁)。忽然發現對這個方法的瞭解還不夠,所以回來查了資料,看了v8引擎的實現和ECMA標準,在這分享一下個人總結。git
先給幾個結論把,而後咱們再從ECMA標準去看這個方法。github
let a = [1, 20, 13, 110] a.sort() console.log(a) // 輸出[1, 110, 13, 20]
如上,a在調用sort方法後,自身數組被修改。面試
這句話具體來講應該是,sort方法在長數組排序的時候是不穩定的。在v8引擎的裏,對於短數組會使用插入排序,而插入排序是穩定的。對於長數組會使用快速排序,而快速排序通常是不穩定的。具體能夠讀v8引擎的代碼,v8引擎內的數組方法實現,從710行開始。算法
咱們來看一下v8引擎中關於這一部分的代碼數組
if (!IS_CALLABLE(comparefn)) { comparefn = function (x, y) { if (x === y) return 0; if (%_IsSmi(x) && %_IsSmi(y)) { return %SmiLexicographicCompare(x, y); } x = TO_STRING(x); y = TO_STRING(y); if (x == y) return 0; else return x < y ? -1 : 1; }; }
能夠看出,在不傳遞comparefn這個參數的狀況下,默認會使用轉換爲的字符串的諸個字符的Unicode位點進行排序。另外值得注意的一點是,undefined在默認狀況下老是會被排在數組的最後,這一點能夠參考ECMA-262標準中關於Array.prototype.sort(comparefn)的描述。瀏覽器
When the SortCompare operatoris called with two arguments x and y, the
following steps are taken:ide
- If x and y are both undefined, return +0.
- If x is undefined, return 1.
- If y is undefined, return −1.
- If the argument comparefn was not provided in the call to sort, go to step 7.
- Call comparefn with arguments x and y.
- Return Result(5).
- Call ToString(x).
- Call ToString(y).
- If Result(7) < Result(8), return −1.
- If Result(7) > Result(8), return 1.
- Return +0.
如下是我簡單翻譯的規則:函數
當比較操做函數用x,y兩個參數調用的時候,會按照接下來的步驟進行:prototype
- 若是x,y都是undefined,返回 +0
- 若是x是undefined,返回 1
- 若是y是undefined,返回 -1
- 若是沒有提供comparefn,跳至第七步
- 用comparefn比較x,y
- 返回第五步的比較結果
- x.toString()
- y.toString()
- 若是第八步大於第七步,返回-1
- 若是第七步大於第八步,返回1
- 返回+0
所以[1, 20, 2, 10].sort()的結果會是[1, 10, 2, 20],而不是預期的[1, 2, 10, 20]。翻譯
另外關於如何根據x,y比較結果進行排序,有如下規則:
因此sort方法返回的數組永遠是該方法認爲的升序數組。咱們要作的事情就是令咱們想要放在後面的數大於放在前面的數。
好比咱們想要返回一個降序的數字數組傳入的comparefn應該是 (a, b) => b - a
參考資料: