前言:
針對於前端開發者來講、數組排序的應用場景其實並不多,大多數情況下都是后台數據排序之后再返回給前端。但是很多面試題中會經常遇到數組排序的問題,經典案例有冒泡排序、插入排序、選擇排序等等... 邏輯性比較強硬。為了追求完美、拒絕花里胡哨,所以今天寫一篇以ES6相關知識實現排序的文章、並且掛載至原型鏈上方便使用,希望對大家的開發有所幫助!
技術點:
ES6中 sort()方法、箭頭函數,prototype原型、繼承。
首先、簡單看一下 sort() 能做什么事情:
sort():方法用原地計算對數組的元素進行排序,並返回排序之后的數組。
-
//sort的基本使用
-
let arr = [
8,
1,
4,
3,
7,
9]
-
let Arr = [
21,
55,
29,
105,
45]
-
console.log(arr.sort())
//[1, 3, 4, 7, 8, 9]
-
console.log(Arr.sort())
// [105, 21, 29, 45, 55]
由上述代碼可知:sort()方法只能對0-9以內的數組進行正確排序,兩位數以上的數組項雖然給出了返回值,但卻並不是排序后的結果。這是因為sort()是內部做的是根據ASCLL碼進行排序的,並不是根據數值大小排序。那這個方法連兩位數以上的數字都無法進行正規排序處理,跟咸魚有什么區別呢?
重點來了:sort()可以接收一個攜帶兩個形參的callback(a,b),即a、b是兩個即將要比較大小的元素,且必須要有返回值。
當callback的返回值是正數時、那么 b 會被排列到 a 之前;
當callback的返回值是負數時、那么 a 會被排列到 b 之前;
當callback的返回值是為 0 時、那么 a 與 b 的位置保持不變;
sort每執行一次會根據返回值調換兩個參數a、b在原數組中的位置;
看完上面的描述你會很蒙圈,你一定會問返回值在哪?參數 a b 的實參是誰?這些當你看懂下面代碼之后統統小兒科!
-
//sort 內部寫法
-
let Arr = [
56,
21,
29,
105,
45]
-
Arr.sort(
function(a, b) {
//callback
-
if (a > b) {
// a b 分別是Arr中的 56 21
-
return
1
//返回正數 ,b排列在a之前
-
}
else {
-
return
-1
//返回負數 ,a排列在b之前
-
}
-
})
-
console.log(Arr)
//[21, 29, 45, 55, 105]
執行邏輯:
需要注意的是callback( a , b )接收的兩個參數分別是a = > 當前項、b當前項的下一項,若當前項與下一項位置不變時,b為下一項索引-1;判斷遍歷結束的條件是b參數取不到值 即結束,舉例上述代碼中第三輪第二次執行時 當前項的索引是3 那么b為下一項,即4 數組中取不到第4項,不滿足繼續遍歷條件,結束遍歷!
談談返回值:上述代碼寫的返回值 1 與 -1 只是象征性的代表 1為正數 -1為負數,不論你代碼寫什么返回值,sort內部只會去判斷你的返回值是正數還是負數,哪怕等式成立返回100 不成立返回-10000都是可行的。
解釋簡寫方式:
-
//簡寫 最終版
-
let Arr = [
56,
21,
88,
10,
5,
77]
-
Arr.sort(
(a, b) => a - b)
//箭頭函數不加大括號指向這個函數的返回值,可以不寫return關鍵字
-
console.log(Arr)
//[5, 10, 21, 56, 77, 88]
由上圖可知,回調函數內部的處理方式是a - b ,而不再是對比兩個數。這是因為對比兩個數的這一步操作是sort去做的,你只需要規定返回值即可,恰好數學定義大數 - 小數 = 正數 、小數 - 大數 = 負數
舉例 56 - 21 = 35 為正數、則返回值為正數,正數代表改變位置;
21 - 88 = 35 為負數、則返回值為負數,負數代表改變位置;
如果數學中大數 - 小數 ≠ 正數 、小數 - 大數 ≠ 負數,就不能這么簡寫。所以要明確的是sort內部做的是互相對比 而不是互減;
掛載至原型:MySort()
我們也可以模擬Arrar對象繼承原型鏈上的寫法,定義自己的數組操作方法,實現直接 Arr.MySort()就可以自己排序:
-
//掛載原型
-
Array.prototype.MySort =
function() {
-
return
this.sort(
(a, b) => a - b)
//箭頭函數不加大括號時指向這個函數的返回值,可以不寫return關鍵字
-
}
-
-
let Arr = [
56,
21,
88,
10,
5,
77]
-
Arr.MySort()
//調用
-
console.log(Arr)
// [5, 10, 21, 56, 77, 88]
需要注意的是MySort中this指向被調用者,即誰掉他 他就指向誰,如果此處使用箭頭函數那么this指向window對象!
在開發過程中還是建議大家使用 if 的寫法,因為這樣簡寫 寫法看起來逼格很高,但是不一定人人都知道你這樣寫是什么意思,更建議不要無注釋的在原型鏈上掛載任何自定義方法,說不定后期維護你代碼的程序猿就會去百度搜索MySort的用法,搜不到還會口吐芬芳說百度辣雞。不利於代碼后期的維護,最好的代碼不是寫的少,而是人人都看得懂!
如果我的博客幫助你解決了開發問題,請不要吝嗇你的小紅心哦!❤
● 若有錯誤歡迎指出、及時修正 ●