「高階函數」是個咱們常常遇到的術語,英文名叫「higher-order function」,對於新手而言,還挺神祕。今天,咱們就來探討下高階函數。前端
接收函數做爲參數或者返回函數的函數面試
大白話就是:bash
咱們這裏舉兩個例子來覆蓋下上文的定義,其中,例一爲接收函數
做爲參數的高階函數,例二爲返回函數
的高階函數。前端框架
咱們定義了一個叫evaluatesToFive
的函數,接收兩個參數:第一個參數是一個數字,第二個參數是一個函數。在函數evaluatesToFive
中,將參數一(數字)傳入參數二(函數)markdown
function evaluatesToFive(num, fn) { return fn(num) === 5; } 複製代碼
使用的場景:閉包
function divideByTwo(num) { return num / 2; } evaluatesToFive(10, divideByTwo); // true evaluatesToFive(20, divideByTwo); // false 複製代碼
哈哈,雖然函數自己用處不大,可是對描述高階函數來講,很簡單易懂。框架
本例中,咱們建立函數multiplyBy
,接收一個數字做爲參數,並返回一個新的函數ide
function multiplyBy(num1) { return function(num2) { return num1 * num2; }; } 複製代碼
使用場景:函數
const multiplyByThree = multiplyBy(3);
const multiplyByFive = multiplyBy(5);
multipyByThree(10); // 30
multiplyByFive(10); // 50
複製代碼
是否是有點感受了,經過生成新的函數以達到更具體的目的。oop
本例中,咱們建立一個函數去檢測新用戶的註冊信息是否能經過檢驗規則:
新用戶的註冊信息大概是這樣:
const newUser = { age: 24, password: 'some long password', agreeToTerms: true, }; 複製代碼
接下來,咱們來建立三個驗證函數,經過返回true
,不然返回false
function oldEnough(user) { return user.age >= 18; } function passwordLongEnough(user) { return user.password.length >= 8; } function agreeToTerms(user) { return user.agreeToTerms === true; } 複製代碼
接下來,該主角登場了,咱們須要建立一個高階函數來一次性完成全部的驗證。參數一是新用戶註冊信息,剩下的參數是咱們上文建立的三個驗證函數。在函數體中依次執行驗證:
function validate(obj, ...tests) { for (let i = 0; i < tests.length; i++) { if (tests[i](obj) === false) { return false; } } return true; } 複製代碼
使用:
const newUser1 = { age: 40, password: 'tncy4ty49r2mrx', agreeToTerms: true, }; validate(newUser1, oldEnough, passwordLongEnough, agreeToTerms); // true const newUser2 = { age: 40, password: 'short', agreeToTerms: true, }; validate(newUser2, oldEnough, passwordLongEnough, agreeToTerms); // false 複製代碼
到目前爲止,已經很棒了,繼續看下去,看咱們怎麼改進
上文中,咱們使用validate
函數的時候須要傳入多個驗證函數(oldEnough, passwordLongEnough, agreeToTerms),這違反了最少知識原則
(有興趣的同窗們能夠去了解下最少知識原則),看咱們怎麼將之繼續改進:
function createValidator(...tests) { return function(obj) { for (let i = 0; i < tests.length; i++) { if (tests[i](obj) === false) { return false; } } return true; }; } 複製代碼
這個createValidator
函數牛逼了,它接收任意數量的函數做爲參數,返回值也是個函數。因此這個createValidator
也是個高階函數。
使用:
const userValidator = createValidator( oldEnough, passwordLongEnough, agreeToTerms ); userValidator(newUser1); // true userValidator(newUser2); // false 複製代碼
看出什麼門道了沒?經過函數createValidator
生成更具體的驗證函數userValidator
,再使用userValidator
去驗證新用戶的註冊信息。多麼精彩的高階函數!意猶未盡的同窗們能夠再學習下另外一個術語柯里化
!
本小文,咱們一塊兒探討了JS中的高階函數,千萬不要覺得高階函數只是一道面試題。前端框架中很火的高階組件
也是引用自高階函數。高階函數在咱們平常開發中常常會使用到,用好了,能夠將不少複雜的業務邏輯進行解耦,對於代碼的可讀性和可維護性頗有意義!文中也用到了閉包的知識,聰明的你發現了嗎?不要讓本身的知識永遠躺在面試題中哦!