<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
我們不妨以兩數相加為例子,遞進說明。
我們通常是這樣寫一個函數來求得 兩數相加 的值:
function sum(a,b){ console.log(a+b) } sum(1,2)
這樣寫一點毛病沒有!
不過呢?問題總會在發展中產生,產品經理又要加一個值,需求:三數相加;
咱通常來說,第一時間,就在原基礎上,直接再加一個引數就是了;
於是,修改後像是這樣:
function sum(a,b,c){ console.log(a+b+c) } sum(1,2,3)
問:這樣寫,有毛病嗎??
答:太有毛病了!
這樣一改,既違反了:“開閉原則”、又違反了:“單一職責原則”。
為不太熟悉設計原則的小夥伴們,簡單解釋下:
首先,咱修改了 sum 函數的傳參以及內部的呼叫 ⇒ 則違反“開閉原則”
其次,sum 函數本來只負責兩數相加,修改後,它又負責三數相加,職責已經發生了變化 ⇒ 則違反 “單一職責原則”;
如果正規按照單一責任來寫,應該是:
// 負責兩數相加 function sum2(a,b){ console.log(a+b) } // 負責三數相加 function sum3(a,b,c){ console.log(a+b+c) }
事實上,是不可能這樣去寫的,因為如果有一萬個數相加,得寫一萬個函數。
而 加法只有一個!! 不管你最終要加幾個值,總是要一個加一個。
於是乎,我們設想,能不能寫一個這樣的函數:它的功能,就是“加”,引數跟幾個,我就加幾個。
// 負責「加法」, function addCurry(){ ... ... ... } addCurry(1)(2) // 兩數相加 addCurry(1)(2)(3) // 三數相加 ... addCurry(1)(2)(3)...(n) // n 數相加
沒錯,這個函數就是:柯里化!!(或者說這個過程叫柯里化,這個思想叫柯里化,本瓜認為這裡不需要太死扣定義)
接著,我們一步步來試試,它會是怎樣構成的?
為了能夠實現一個加一個,即儲存引數的目的,我們想一想,還有什麼法寶?
沒錯,JS 奧義:閉包!
其實,本瓜時常想,閉包的終極祕密是什麼?最後將其理解為 4 個金光閃閃的大字:延遲處理!
什麼意思?簡單解釋下:
function directHandle(a,b){ console.log("直接處理",a,b) } directHandle(111,222) // 直接處理 111 222 function delayHandle(a){ return function(b){ console.log("延遲處理",a,b) } } delayHandle(111) // ƒ (b){ // console.log("延遲處理",a,b) // }
如上 delayHandle(111)
不像 directHandle(111,222)
直接列印值,而是先返回一個函數 f(b)
;111 也被臨時儲存了,delayHandle(111)(222)
,則得到相同的輸出。這就是:延遲處理的思想。
另外補一句:
延遲處理是函數語言程式設計的精華所在,在不能保證每個函數都是純函數的前提下,在管道處理的最後,再進行處理,能最大程度的保證減少副作用。也就是 Monad 思想,此處不做展開。
言歸正傳,於是乎,我們借用閉包來實現最初版的柯里化:
// 兩數相加 function addCurry(a){ return function(b){ console.log(a+b) } } addCurry(1)(2) // 三數相加 function addCurry(a){ return function(b){ return function(c){ console.log(a+b+c) } } } addCurry(1)(2)(3)
寫兩個閉包的過程,聰明的你一定就明白了,這樣一直寫下去,不就是遞迴嗎?!
於是乎,我們知道,當引數是 n 個的時候,需要遞迴 n-1 次 return function
於是乎,addCurry 寫法如下:
let arr = [] function addCurry() { let arg = Array.prototype.slice.call(arguments); // 遞迴獲取後續引數 arr = arr.concat(arg); if (arg.length === 0) { // 如果引數為空,則判斷遞迴結束 return arr.reduce((a,b)=>{return a+b}) // 求和 } else { return addCurry; } } addCurry(1)(2)(3)()
OK,至此,,大功告成!!
以上,用最簡單的程式碼解釋了 —— 為什麼我說:柯里化 == 閉包+遞迴 ?
柯里化是一種思想,上面的 addCurry 可以說是最簡單的一種實踐。在函數語言程式設計中,Curry 更是大放異彩,比如 compose(fn1)(fn2)(fn3)…(fnN)(args) 等等。
如果以後有人再問你柯里化,可以往這個方向上答。。。
以上就是閉包結合遞迴等於柯里化原理解析的詳細內容,更多關於閉包結合遞迴等於柯里化的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45