(話很少說,填以前的坑)數組
在js裏,咱們對於function的用法,可能大部分狀況下都仍是處於調用,形如app
function add(x, y) { return x + y } console.log(add(1, 2)) //函數調用 返回3
可是有一個apply()
函數,使咱們擁有另外一種方式來應用函數,例如函數
function add(x, y) { return x + y } console.log(add.apply(null, [1, 2])) //返回3
apply
的第一個參數爲null
時,this
指向全局對象(忘記請自行查閱查mdn),在上面這個例子裏,經過apply
來應用函數的時候,效果和調用函數徹底一致。this
從前文可知,函數調用就是讓一個參數集合(前面的[1,2])應用到函數(前文的add函數)中,那部分應用就是考慮只傳遞部分參數,而非全部參數。 仍是上面add
函數的例子,咱們但願實現下面的形式(在下一節具體實現):prototype
var newAdd = add.apply(null,[1])//部分應用 只傳遞了第一個參數 newAdd.apply(null,[2]) //3
分析上面的代碼可知,實現部分應用的關鍵是:部分應用的返回結果是一個新的函數,該函數能夠被傳入其餘參數再次調用code
如今進入正題,前面講完了部分應用
。curry化的含義,就是使函數理解並處理部分應用的過程對象
繼續按照上文的思路實現add
函數的curry化:io
function add(x, y) { // 若是隻傳遞部分參數,則部分應用,返回一個新的函數 if (y === undefined) { return function (y) { return x + y } } return x + y //若是傳遞全部參數,直接徹底應用 } //運行前一節代碼 var newAdd = add.apply(null, [1]) console.log(newAdd.apply(null, [2])) //3 console.log(newAdd.apply(null, [5])) //6
上述代碼已經實現了前一節的要求,能夠看到curry的結果就是:通過一次curry的newadd
函數,變成一個與1求和的函數,接應用的時候只傳遞一個參數,都能獲得對應的結果,同時也能夠看出這個curry太侷限。接下來咱們就要考慮,如何實現通用的curry函數console
先回憶前面的過程,來思考curry一個函數的實現步驟:function
注:入參函數-要被curry的函數,結果函數-被curry以後的函數*
文字比較抽象,能夠直接看實如今回來看過程:
function commonCurry(fn) { var slice = Array.prototype.slice, storedArgs = slice.call(arguments, 1) //使用slice是爲了把arguments轉換成真正的數組,剝離此處第一個參數,是由於第一個參數是fn return function () { var newArgs = slice.call(arguments), //新傳入的參數 args = storedArgs.concat(newArgs) return fn.apply(null, args) } } //使用舉例 function add(a, b) { return a + b } var newAdd = commonCurry(add, 10) console.log(newAdd(5)) // 多個參數 function add2(a, b, c, d) { return a + b + c + d } var newAdd2 = commonCurry(add2, 10, 10) console.log(newAdd2(5, 4))//29 // 屢次curry var newAdd3 = commonCurry(newAdd2, 10) console.log(newAdd3(10))//40
以後會嘗試以更簡潔明瞭的方式來寫文章。若是內容有錯誤的地方歡迎指出(以爲看着不理解不舒服想吐槽也徹底沒問題);若是對你有幫助,歡迎點贊和收藏,轉載請徵得贊成後著明出處,若是有問題也歡迎私信交流,主頁添加了郵箱地址。