講一講JS中的高階函數

“高階函數”是個我們經常遇到的術語,英文名叫“higher-order function”,對於新手而言,還挺神秘。今天,我們就來探討下高階函數。

定義

接收函數作為參數或者返回函數的函數

大白話就是:

  1. 首先是個函數
  2. 參數或者返回值是函數

舉例子

我們這裡舉兩個例子來覆蓋下上文的定義,其中,例一為接收函數作為參數的高階函數,例二為返回函數的高階函數。

例一:函數作為參數

我們定義了一個叫evaluatesToFive的函數,接收兩個參數:第一個參數是一個數字,第二個參數是一個函數。在函數evaluatesToFive中,將參數一(數字)傳入參數二(函數)

<code>function evaluatesToFive(num, fn) {
return fn(num) === 5;
}/<code>

使用的場景:

<code>function divideByTwo(num) {
return num / 2;
}

evaluatesToFive(10, divideByTwo);
// true

evaluatesToFive(20, divideByTwo);
// false/<code>

哈哈,雖然函數本身用處不大,但是對描述高階函數來說,很簡單易懂。

例二:返回函數

本例中,我們創建函數multiplyBy,接收一個數字作為參數,並返回一個新的函數

<code>function multiplyBy(num1) {
return function(num2) {
return num1 * num2;
};
}/<code>

使用場景:

<code>const multiplyByThree = multiplyBy(3);
const multiplyByFive = multiplyBy(5);

multipyByThree(10); // 30

multiplyByFive(10); // 50/<code>

是不是有點感覺了,通過生成新的函數以達到更具體的目的。

更復雜的應用實例

本例中,我們創建一個函數去檢測新用戶的註冊信息是否能通過檢驗規則:

  • 大於18歲
  • 密碼長度大於8
  • 同意用戶協議

新用戶的註冊信息大概是這樣:

<code>const newUser = {
age: 24,
password: 'some long password',
agreeToTerms: true,
};/<code>

接下來,我們來創建三個驗證函數,通過返回true,否則返回false

<code>function oldEnough(user) {
return user.age >= 18;
}

function passwordLongEnough(user) {
return user.password.length >= 8;
}

function agreeToTerms(user) {
return user.agreeToTerms === true;
}/<code>

接下來,該主角登場了,我們需要創建一個高階函數來一次性完成所有的驗證。參數一是新用戶註冊信息,剩下的參數是我們上文創建的三個驗證函數。在函數體中依次執行驗證:

<code>function validate(obj, ...tests) {
for (let i = 0; i < tests.length; i++) {
if (tests[i](obj) === false) {
return false;
}
}
return true;
}/<code>

使用:

<code>

到目前為止,已經很棒了,繼續看下去,看我們怎麼改進

繼續進化

上文中,我們使用validate函數的時候需要傳入多個驗證函數(oldEnough, passwordLongEnough, agreeToTerms),這違反了最少知識原則(有興趣的同學們可以去了解下最少知識原則),看我們怎麼將之繼續改進:

<code>function createValidator(...tests) {
return function(obj) {
for (let i = 0; i < tests.length; i++) {
if (tests[i](obj) === false) {
return false;
}
}
return true;
};
}/<code>

這個createValidator函數牛逼了,它接收任意數量的函數作為參數,返回值也是個函數。所以這個createValidator也是個高階函數。

使用:

<code>const userValidator = createValidator(
oldEnough,
passwordLongEnough,
agreeToTerms
);

userValidator(newUser1); // true
userValidator(newUser2); // false/<code>

看出什麼門道了沒?通過函數createValidator生成更具體的驗證函數userValidator,再使用userValidator去驗證新用戶的註冊信息。多麼精彩的高階函數!意猶未盡的同學們可以再學習下另一個術語柯里化!

結語

本小文,我們一起探討了JS中的高階函數,千萬不要以為高階函數只是一道面試題。前端框架中很火的高階組件也是引用自高階函數。高階函數在我們日常開發中經常會使用到,用好了,可以將很多複雜的業務邏輯進行解耦,對於代碼的可讀性和可維護性很有意義!文中也用到了閉包的知識,聰明的你發現了嗎?不要讓自己的知識永遠躺在面試題中哦!

以上內容都是我自己的一些感想,分享出來歡迎大家指正,順便求一波關注,有問題或者需要學習資料的夥伴可以~

講一講JS中的高階函數


敲黑板

關注 +轉發+私信“Java”

關注 +轉發+私信“Java”

關注 +轉發+私信“Java”


講一講JS中的高階函數


分享到:


相關文章: