本篇文章主要是介紹一下標題里面的概念,在面試的時候經常文檔,結合閱讀到的資料,結合本人的個人見解出品了該文章,如有寫的不好的地方或理解有誤的,還望閣下多多指教。
1、高階函數
什么是高階函數?
-
接受一個或多個函數作為輸入
-
輸出一個函數
在React中的高階組件本質上就是高階函數。我們在開發umi搭建出來的項目的時候,那個withRouter本質上就是一個高階函數。
2、柯里化
柯里化概念:將一個多元函數,轉成一個依次調用的單元函數。
柯里化特點:
- 返回一個函數
- 當接受參數數量與原函數形參數量相同,執行原函數
- 當小于形參數值,返回一個函數,用接收剩余參數,直到參數數量保持一致,才開始執行原函數。
舉個例子,比如說我們有一個sum函數,接收a,b,c,d這四個參數,經過curry這個函數以后,可以依次傳參數:
function sum(a, b, c, d) {console.log(a, b, c, d);
}var _sum = curry(sum);
var A = _sum(1)
var B = A(2)
var C = B(3)
var D = C(4)
那么curry這個函數具體是怎樣的呢?來看一下代碼:
function curry(fn) {return function curriedFn() {var args = Array.prototype.slice.call(arguments)if (args.length < fn.length) {// 參數不同return function() {var args2 = Array.prototype.slice.call(arguments)// 開始遞歸return curriedFn.apply(null, args.concat(args2))}}// 參數相同return fn(...args)}
}
接下來看一下在面試的時候見到的一個面試真題:
實現一個方法add(1)(2)(3)
這個題目還可以變形,實現一個方法add(1,2)(3)或者add(1)(2,3);
不管如何變形,使得最后加和的結果都是相同的。
這道面試題我在面試的時候真的見面試官問過,其實是考察柯里化和閉包的,我當時對于柯里化這個概念理解的不是很透徹,沒寫出讓面試官滿意的結果,結果面試掛了,掛了不怕,來復盤一下吧,下次面試在遇到同樣的問題,一定要能寫出來呀,來看一下答案吧:
function add() {var args = Array.prototype.slice.call(arguments);var currying = function() {args.push(...arguments);return currying;};currying.getSum = function () {return args.reduce(function (a, b) {return a + b;});}return currying;
}console.log('查看demo:', add(1,2)(3)(4,5).getSum());
3、純函數
純函數定義:純函數是這樣一種函數,即相同的輸入,永遠會得到相同的輸出,而且沒有任何可觀察的副作用。
比如數組的 slice
和 splice,
-
slice
符合純函數的定義:因為對相同的輸入它保證能返回相同的輸出; -
splice
卻不同:會產生可觀察到的副作用,即這個數組永久地改變了;