【重溫基礎】JS中的常用高階函式介紹

pingan8787發表於2019-02-16

Ps. 晚上加班到快十點,回來趕緊整理整理這篇文章,今天老大給我推薦了一篇文章,我從寫技術部落格中收穫到了什麼?- J_Knight_,感受也是很多,自己也需要慢慢養成記錄部落格的習慣,即使起步艱難,難以堅持,但還是要讓自己加油加油。
前兩天把我整理的【複習資料】ES6/ES7/ES8/ES9資料整理(個人整理)要分享給大家啦。

正文內容開始:

1.介紹

個人簡單理解為,一個函式可以接收其他函式作為引數,這種函式便稱為高階函式,而主要目的就是為了能接收其他函式作為引數。

Q: 為什麼可以接收一個函式作為引數?
A: 因為函式可以接收變數作為引數,而變數可以宣告一個方法。

簡單例項:

function a (x){
    return `hi ` + x;
}
function f (a, b){
    return a(b);
}
f(a, `leo`);   // "hi leo"

這段程式碼的意思:定義方法f,接收兩個引數,方法a和變數b,在方法a中返回一段字串,當執行方法f並傳入引數方法a和引數b的時候,返回"hi leo"

也可以直接呼叫JS內建方法:

let a = 3, b = -2;
function my_abs (val, fun){
    return fun(val);
}
my_abs(a, Math.abs);  // 3
my_abs(b, Math.abs);  // 2

2.常用高階函式

2.1 map()

map()方法的作用是:接收一個函式作為引數,對陣列中每個元素按順序呼叫一次傳入的函式並返回結果,不改變原陣列,返回一個新陣列
通常使用方式:arr.map(callback()),更多詳細介紹可以參考 MDN Array.map()
引數

  • arr : 需要操作的陣列;
  • callback(currentValue, index, array, thisArg) : 處理的方法,四個引數;

      1. currentValue 當前處理的元素的
      1. index 當前處理的元素的索引,可選
      1. array 呼叫map()方法的陣列,可選
      1. currentVthisArgalue 執行 callback 函式時使用的 this 值,可選

返回值
返回一個處理後的新陣列。

例項

let arr = [1, 3, -5];
let a1 = arr.map(Math.abs);  
// a1 => [1, 3, 5];

let a2 = arr.map(String);
// a2 => ["1", "3", "-5"]

let a3 = arr.map(function (x){
    return x + 1;
})
// 等價於 a3=arr.map(x => x+1)
// a3 => [2, 4, -4]

對比 for...in 迴圈,map()書寫起來更加簡潔:

let arr = [1, 3, -5];
let a1 = [];
for (var i=0; i<arr.length; i++){
    a1.push(arr[i] + 1); 
}
// a1 => [2, 4, -4]

map()作為高階函式,事實上它把運算規則抽象了。

2.2 reduce()

reduce()方法的作用是:接收一個函式,對陣列進行累加操作,把累計結果和下一個值進行操作,最後返回最終的單個結果值。

通常使用方式:arr.reduce(callback(), initValue),更多詳細介紹可以參考 MDN Array.reduce()

引數

  • callback(returnValue, currentValue, currentIndex, array) : 累記器的方法,四個引數:

      1. returnValue 上一次處理的返回值,或者初始值
      1. currentValue 當前處理的元素的,可選
      1. currentIndex 當前處理的元素的索引,可選
      1. array 呼叫reduce()方法的陣列,可選
  • initValue 初次呼叫callback()時候returnValue引數的初始值,預設陣列第一個元素,可選

返回值
返回一個最終的累計值。

例項

  1. 陣列求和
let arr = [1, 3, -5];
let sum1 = arr.reduce((res, cur) => res + cur);
// sum1 => -1

let sum2 = arr.reduce((res, cur) => res + cur , 1);
// sum1 => 0
  1. 二維陣列轉化為一維
let arr = [[1, 2], [3, 4], [5, 6]];
let con = arr.reduce((res, cur) => res.concat(cur));
// con => [1, 2, 3, 4, 5, 6]

2.3 filter()

filter()方法的作用是:接收一個函式,依次作用陣列每個元素,並過濾符合函式條件的元素,將剩下的陣列作為一個新陣列返回。

通常使用方式:arr.filter(callback(), thisArg),更多詳細介紹可以參考 MDN Array.filter()

引數

  • callback(ele, index, array) : 過濾條件的方法,當返回true則儲存該元素,反之不保留,三個引數:

      1. ele 當前處理的元素
      1. index 當前處理的元素的索引,可選
      1. array 呼叫filter()方法的陣列,可選
  • thisArg 執行 callback 時的用於 this 的值,可選

返回值
返回一個過濾剩下的元素組成的新陣列。

例項

  1. 過濾奇數值
let arr = [1, 2, 3, 4, 5, 6];
let res = arr.filter(x => x % 2 != 0);
// res => [1, 3, 5]
  1. 過濾不滿足條件的值
let arr = [1, 2, 3, 4, 5, 6];
let res = arr.filter(x => x > 3);
// res => [4, 5, 6]
  1. 過濾空字串
let arr = [`a`, ``, null, undefined, `b`, ``];
let tri = arr.filter(x => x && x.trim());
// tri => ["a", "b"]

總結下: filter()主要作為篩選功能,因此核心就是正確實現一個“篩選”函式。

2.4 sort()

sort()方法的作用是:接收一個函式,對陣列的元素進行排序,並返回排序後的新陣列。預設排序順序是根據字串Unicode碼點

通常使用方式:arr.sort(fun()),更多詳細介紹可以參考 MDN Array.sort()
compareFunction 可選
用來指定按某種順序進行排列的函式。如果省略,元素按照轉換為的字串的各個字元的Unicode位點進行排序。
引數

  • fun(a, b) : 指定按某種順序進行排列的函式,若省略則按照轉換為的字串的各個字元的Unicode位點進行排序,兩個可選引數:

fun() 返回 ab兩個值的大小的比較結果,sort()根據返回結果進行排序:

  • fun(a, b) 小於 0 ,則 a 排在 b 前面;
  • fun(a, b) 等於 0 ,則 a b 位置不變;
  • fun(a, b) 大於 0 ,則 a 排在 b 後面;

返回值
返回排序後的新陣列,並修改原陣列

例項

  1. 升序降序陣列
let arr = [1,5,2,3];
let sort1 = arr.sort();
// 等同於 let sort1 = arr.sort((a, b) => a - b);
// sort1 => [1, 2, 3, 5]

let sort2 = arr.sort((a, b) => b - a);
// sort2 => [5, 3, 2, 1]
  1. 字串排序
let arr1 = [`AA`, `CC`, `BB`];
let sort1 = arr1.sort();
// sort1 => ["AA", "BB", "CC"]

let arr2 = [`AA`, `aa`, `BB`];
let sort2 = arr2.sort();
// sort2 => ["AA", "BB", "aa"]

let arr3 = [`AA`, `aa`, `BB`];
let sort3 = arr3.sort((a, b) => a.toLowerCase() > b.toLowerCase());
// sort3 => ["AA", "aa", "BB"]
// 也可以寫成:
let sort3 = arr3.sort((a, b) => {
    let s1 = a.toLowerCase();
    let s2 = b.toLowerCase();
    return s1 > s2 ? 1 : s1 < s2 ? -1 : 0;
})

總結下: sort()主要作為排序功能,因此核心就是正確實現一個“排序”函式。

3. 參考文章

分享的內容比較簡單,但是還是希望能幫助到需要的人哈。~~感謝

Author 王平安
E-mail pingan8787@qq.com
博 客 www.pingan8787.com
微 信 pingan8787
每日文章推薦 https://github.com/pingan8787…
ES小冊 es.pingan8787.com

歡迎關注微信公眾號【前端自習課】每天早晨,與您一起學習一篇優秀的前端技術博文 .

相關文章