(JavaScript) Array.prototype.sort() in Chrome and Firefox

Jerry Wu
4 min readMay 22, 2021

--

Array.prototype.sort() 是一個非常容易誤用的方法,它讓許多 JavaScript 新手感到相當困惑,本篇將介紹如何正確使用 Array.prototype.sort()。

sort() 的用法

arr.sort([compareFunction])

可以發現我們在使用 array.sort() 方法時可以接受一個回調函數,MDN 將它稱為compareFunction。

根據定義,如果沒有傳入 compareFunction,那麼預設就會自動將陣列中的 elements 轉成字串,並依照 UTF-16 code units order 排序。這就是為什麼 100 會排在 9 前面的原因。

.sort() in Chrome
.sort() in Firefox

如果有傳入 compareFunction,那麼 compareFunction 就會依照 Timsort(Chrome) 演算法抓取兩個 elements 進行比較,然後回傳結果。case 如下:

1. compareFunction(a, b) 回傳 0 → a 排在 b 前面

2. compareFunction(a, b) 回傳大於 0 的值 → b 排在 a 前面

3. compareFunction(a, b) 回傳小於 0 的值 → a 排在 b 前面

所以通常如果想要遞增排序,會將回傳值設定為 a-b,這樣一來,如果前面的 a 小於後面的 b,那麼 a 減 b 就會是小於 0 的值,根據上面的規則,a 就會排在 b 的前面,整個陣列也就會是遞增排序。

// 遞增排序
arr.sort((a, b) => {
return a - b;
});

反之如果要遞減排序,那麼就只要將回傳值改成 b-a。

// 遞減排序
arr.sort((a, b) => {
return b- a;
});

看到這裡,其實就會發現我們可以在 compareFunction 裡面做任何事情,然後配合剛剛提到的規則來影響最後排序結果。

當然我們也可以在 compareFunction 裡面放入 console.log 來看看演算法是如何實際抓取 elements 來進行比較。

// 若是要對數字陣列進行遞增排序// Correct
[100, 3, 2].sort((a, b) => {
console.log(`a = ${a}, b = ${b}`);
return a - b;
});
// Incorrect
[100, 3, 2].sort();

以下讓我們來看看在 Chrome 與 Firefox 實際上運作的情況吧!

.sort() in Chrome
.sort() in Firefox

由上述範例配合 console.log 可以得知 Chrome 與 Firefox 都會得到相同的答案,但各家瀏覽器在實作 Sort 的演算法卻是不同的!

下回我們將來聊聊以下兩個演算法,分別為:

Firefox .sort() 所使用的 Merge sort

以及

Chrome .sort() 所使用的 Timsort

謝謝你的閱讀!如果有任何回饋或疑問,歡迎留言給我!
如果對我的文章有興趣,請不吝按下Follow & Clap!
每個月都會認真更新文章唷😊 千萬別錯過了~

--

--

Jerry Wu

Full-Stack Engineer,熱愛接觸Web前後端、DevOps相關技術與知識,喜歡分享、旅遊和桌球🏓