摘要:方法可以接受一個可選的參數,比較回調函數。方法會修改原本數組輸出如上,在調用方法后,自身數組被修改。對于長數組會使用快速排序,而快速排序一般是不穩定的。所以方法返回的數組永遠是該方法認為的升序數組。
前幾天在某公司面試的時候被問到關于這個方法的默認值的問題(然而面試官跟我說的其實是錯的,當場我還不夠底氣去反駁)。突然發現對這個方法的了解還不夠,因此回來查了資料,看了v8引擎的實現和ECMA標準,在這分享一下我的總結。
先給幾個結論把,然后我們再從ECMA標準去看這個方法。
sort方法會修改原本數組。
sort方法是不穩定的。
sort方法可以接受一個可選的參數,comparefn(比較回調函數)。
sort方法始終是默認升序的。
1.sort方法會修改原本數組let a = [1, 20, 13, 110] a.sort() console.log(a) // 輸出[1, 110, 13, 20]
如上,a在調用sort方法后,自身數組被修改。
2.sort方法是不穩定的這句話具體來說應該是,sort方法在長數組排序的時候是不穩定的。在v8引擎的里,對于短數組會使用插入排序,而插入排序是穩定的。對于長數組會使用快速排序,而快速排序一般是不穩定的。具體可以讀v8引擎的代碼,v8引擎內的數組方法實現,從710行開始。
3.sort方法可以接受一個可選的參數,ccomparefn(比較回調函數)。我們來看一下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: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兩個參數調用的時候,會按照接下來的步驟進行:
如果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]。
4. sort方法始終是默認升序的。另外關于如何根據x,y比較結果進行排序,有以下規則:
如果 comparefn(a, b) 小于 0 ,那么 a 會被排列到 b 之前;
如果 comparefn(a, b) 等于 0 , a 和 b 的相對位置不變。備注: ECMAScript 標準并不保證這一行為,而且也不是所有瀏覽器都會遵守(例如 Mozilla 在 2003 年之前的版本, 例如v8引擎, 這一點其實就是上面所說的排序不穩定);
如果 comparefn(a, b) 大于 0 , b 會被排列到 a 之前。
所以sort方法返回的數組永遠是該方法認為的升序數組。我們要做的事情就是令我們想要放在后面的數大于放在前面的數。
比如我們想要返回一個降序的數字數組傳入的comparefn應該是 (a, b) => b - a
參考資料:
MDN關于sort算法的文檔
v8引擎數組實現
ECMA-262標準
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/93587.html
摘要:函數作為參數情況,,和是中內置的高階函數。知道了到底啊什么是高階函數,有哪些類型的高階函數。公眾號技術棧路線大家好,我是,公眾號程序員成長指北作者,這篇文章是必知必會系列的高階函數講解。 前言 一道經典面試題: //JS實現一個無限累加的add函數 add(1) //1 add(1)(2) //3 add(1)(2)(3) //6 當大家看到這個面試題的時候,能否在第一時間想到...
摘要:關于我的博客掘金專欄路易斯專欄原文鏈接深度長文數組全解密全文共字,系統講解了數組的各種特性和。構造器構造器用于創建一個新的數組。中聲明的數組,它的構造函數是中的對象。 本文首發于CSDN網站,下面的版本又經過進一步的修訂。 關于 我的博客:louis blog 掘金專欄:路易斯專欄 原文鏈接:【深度長文】JavaScript數組全解密 全文共13k+字,系統講解了JavaScrip...
摘要:快速排序是不穩定的排序算法。瀏覽器的實現不同有什么影響排序算法不穩定有什么影響舉個例子某市的機動車牌照拍賣系統,最終中標的規則為按價格進行倒排序相同價格則按照競標順位即價格提交時間進行正排序。 本文要解決的問題 1、找出 Array.prototype.sort 使用的什么排序算法 2、用一種直觀的方式展示 Array.prototype.sort 的時間復雜度,看看它有多快? 3、...
摘要:本文除了會帶大家了解一些方法后面簡寫為方法的基本定義和用法之外,還會探討一下方法到底是使用的什么排序算法。下面我們來看看方法到底是如何排序的。 ??本文除了會帶大家了解一些Array.prototypr.sort()方法(后面簡寫為sort()方法)的基本定義和用法之外,還會探討一下sort()方法到底是使用的什么排序算法。簡單度娘了一下,網上的那些sort()方法詳解文章,大多只說了...
摘要:數組的特別之處在于,當使用小于的非負整數作為屬性名時數組會自動維護其屬性值。返回的數組包含第一個參數指定的位置和所有到但不含第二個參數指定的位置之間的所有數組元素。數組中只需有一項滿足給定條件則返回。 概念 JavaScript數組是JavaScript對象的特殊形式。數組索引實際上和碰巧是整數的屬性名差不多,使用方括號訪問數組元素就像用方括號訪問對象的屬性一樣。JavaScript將...
閱讀 1593·2021-11-22 15:33
閱讀 1736·2021-11-15 18:01
閱讀 673·2021-10-09 09:43
閱讀 2613·2021-09-22 16:03
閱讀 763·2021-09-03 10:28
閱讀 3558·2021-08-11 10:22
閱讀 2722·2019-08-30 15:54
閱讀 1766·2019-08-30 14:21