JavaScript之ES6數組排序 高逼格!


前言:

針對於前端開發者來講、數組排序的應用場景其實並不多,大多數情況下都是后台數據排序之后再返回給前端。但是很多面試題中會經常遇到數組排序的問題,經典案例有冒泡排序、插入排序、選擇排序等等... 邏輯性比較強硬。為了追求完美、拒絕花里胡哨,所以今天寫一篇以ES6相關知識實現排序的文章、並且掛載至原型鏈上方便使用,希望對大家的開發有所幫助!

技術點:

ES6中 sort()方法、箭頭函數,prototype原型、繼承。

首先、簡單看一下 sort() 能做什么事情:

sort():方法用原地計算對數組的元素進行排序,並返回排序之后的數組。


    
    
   
   
           
  1. //sort的基本使用
  2. let arr = [ 8, 1, 4, 3, 7, 9]
  3. let Arr = [ 21, 55, 29, 105, 45]
  4. console.log(arr.sort()) //[1, 3, 4, 7, 8, 9]
  5. 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 的實參是誰?這些當你看懂下面代碼之后統統小兒科!


    
    
   
   
           
  1. //sort 內部寫法
  2. let Arr = [ 56, 21, 29, 105, 45]
  3. Arr.sort( function(a, b) { //callback
  4. if (a > b) { // a b 分別是Arr中的 56 21
  5. return 1 //返回正數 ,b排列在a之前
  6. } else {
  7. return -1 //返回負數 ,a排列在b之前
  8. }
  9. })
  10. 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都是可行的。

解釋簡寫方式:


    
    
   
   
           
  1. //簡寫 最終版
  2. let Arr = [ 56, 21, 88, 10, 5, 77]
  3. Arr.sort( (a, b) => a - b) //箭頭函數不加大括號指向這個函數的返回值,可以不寫return關鍵字
  4. console.log(Arr) //[5, 10, 21, 56, 77, 88]

由上圖可知,回調函數內部的處理方式是a - b ,而不再是對比兩個數。這是因為對比兩個數的這一步操作是sort去做的,你只需要規定返回值即可,恰好數學定義大數 - 小數 = 正數 、小數 - 大數 = 負數

舉例 56 - 21 = 35 為正數、則返回值為正數,正數代表改變位置;

        21 - 88 = 35 為負數、則返回值為負數,負數代表改變位置;

如果數學中大數 - 小數 ≠ 正數 、小數 - 大數 ≠ 負數,就不能這么簡寫。所以要明確的是sort內部做的是互相對比 而不是互減;

掛載至原型:MySort()

我們也可以模擬Arrar對象繼承原型鏈上的寫法,定義自己的數組操作方法,實現直接 Arr.MySort()就可以自己排序:


    
    
   
   
           
  1. //掛載原型
  2. Array.prototype.MySort = function() {
  3. return this.sort( (a, b) => a - b) //箭頭函數不加大括號時指向這個函數的返回值,可以不寫return關鍵字
  4. }
  5. let Arr = [ 56, 21, 88, 10, 5, 77]
  6. Arr.MySort() //調用
  7. console.log(Arr) // [5, 10, 21, 56, 77, 88]

需要注意的是MySort中this指向被調用者,即誰掉他 他就指向誰,如果此處使用箭頭函數那么this指向window對象!

在開發過程中還是建議大家使用 if 的寫法,因為這樣簡寫 寫法看起來逼格很高,但是不一定人人都知道你這樣寫是什么意思,更建議不要無注釋的在原型鏈上掛載任何自定義方法,說不定后期維護你代碼的程序猿就會去百度搜索MySort的用法,搜不到還會口吐芬芳說百度辣雞。不利於代碼后期的維護,最好的代碼不是寫的少,而是人人都看得懂!


 如果我的博客幫助你解決了開發問題,請不要吝嗇你的小紅心哦!


● 若有錯誤歡迎指出、及時修正 ●


 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM