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