您好,登錄后才能下訂單哦!
這篇文章主要介紹了Javascript currying柯里化是什么,具有一定借鑒價值,需要的朋友可以參考下。希望大家閱讀完這篇文章后大有收獲。下面讓小編帶著大家一起了解一下。
面試題:實現add(1)(2)(3) //結果 = 6,題的核心就是問的js的柯里化
先說說什么是柯里化,看過許多關于柯里化的文章,始終搞不太清楚,例如:柯里化(Currying)是把接受多個參數的函數變換成接受一個單一參數(最初函數的第一個參數)的函數,并且返回接受余下的參數且返回結果的新函數的技術。大多數的blog都是這種說法,說實話我是懵逼的。
我的理解是,curry是一個收集參數的方法,收集夠了去執行函數。
實現前我們先列一下要點
1、收集參數(就像面試題多次執行多個參數)是的利用閉包
2、每次執行參數有多有少例如add(1)(2,3)(4)
3、我們需要知道什么時候參數夠了
//如題 //add(1)(2)(3) //邏輯應該是這樣add(1)執行收集參數1繼續執行收集參數2依次類推直到收集完畢。 function curry(fn) { let arg = []; //用于收集參數 //做一個閉包https://segmentfault.com/a/1190000017824877 return function() { //每執行一次收集一次參數,為什么用concat是因為有時候后是多個參數(2,3) arg = arg.concat([...arguments]); //直到參數收集完成執行fn // 我們需要知道什么時候收集完了,條件就是curry參數fn的參數個數 fn.length //如果收集的參數個數大于等于fn的參數個數執行fn,如果沒有遞歸執行 if (arg.length >= fn.length) { return fn(...arg) } // 參數沒有收集完我們需要繼續收集,遞歸 return arguments.callee } } // 測試一下 let testAdd = curry(add1) // console.log(testAdd(1)(2)(3)) // console.log(testAdd(1, 2)(3)) //console.log(testAdd(1)(2, 3))
一不小心寫完了!
不過不能標題黨,說好的詳解,接下來我們解析一下網上大多數柯里化的實現代碼
function curry(fn) { function _c(restNum, argsList) { return restNum === 0 ? fn.apply(null, argsList) : function(x) { return _c(restNum - 1, argsList.concat(x)); }; } return _c(fn.length, []); }
一眼看不明白沒事,我們多看幾眼。
解析:
1、curry也是接收一個參數(fn)這個是必然
2、返回了一個函數,接收兩個參數,fn.length和一個空數組這個好解
釋,我寫的簡版也說過了,fn.length是為了判斷參數是否收集夠
了,參數傳一個空數組其實也是閉包的一種實現,用來收集參數。
3、里邊是一個三目判斷,看著花里胡哨的沒那么復雜,判斷fn的參數個數如果是0,那就沒必要收集了直接執行fn,至于fn.apply(null,argList)我很明白的大聲說出來會用個apply就到處用嗎?在我看來沒有一分錢用,之所以用是因為argList是一個數組,正好apply正好支持第二個參數是數組,主要看起來很牛逼的樣子。
4、收集參數,fn參數個數不為零,每次收集fn函數參數的個數減一,直到等于0執行fn,這個就沒有我寫的通用了,我一次傳倆就掛了。
再來一個例子:bind方法實現
Function.prototype.bind = function(context) { //返回一個綁定this的函數,我們需要在此保存this let self = this // 可以支持柯里化傳參,保存參數 let arg = [...arguments].slice(1) // 返回一個函數 return function() { //同樣因為支持柯里化形式傳參我們需要再次獲取存儲參數 let newArg = [...arguments] console.log(newArg) // 返回函數綁定this,傳入兩次保存的參數 //考慮返回函數有返回值做了return return self.apply(context, arg.concat(newArg)) } } // 搞定測試 let fn = Person.say.bind(Person1) fn() fn(18)
感謝你能夠認真閱讀完這篇文章,希望小編分享Javascript currying柯里化是什么內容對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業資訊頻道,遇到問題就找億速云,詳細的解決方法等著你來學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。