摘要:簡(jiǎn)單來說,柯里函數(shù)就是只接受一個(gè)參數(shù)的函數(shù),柯里化的起源請(qǐng)參看這篇文章函數(shù)式編程入門教程通常來講,如果三個(gè)數(shù)求和的函數(shù)我們會(huì)這樣寫如果只考慮實(shí)現(xiàn)這個(gè)函數(shù)的柯里化,我們可以這樣做觀察上面兩種不同的寫法可以發(fā)現(xiàn),第二種寫法其實(shí)就是首先把三個(gè)參數(shù)
簡(jiǎn)單來說,柯里函數(shù)就是只接受一個(gè)參數(shù)的函數(shù),柯里化的起源請(qǐng)參看這篇文章:函數(shù)式編程入門教程
通常來講,如果三個(gè)數(shù)求和的函數(shù)我們會(huì)這樣寫:
function _sum3(x, y, z) { return x + y + z }
如果只考慮實(shí)現(xiàn)這個(gè)函數(shù)的柯里化,我們可以這樣做:
function sum3(x) { return function(y) { return function(z) { return x + y + z } } } console.log(sum3(1)(2)(3)) // 6
觀察上面兩種不同的寫法可以發(fā)現(xiàn),第二種寫法其實(shí)就是首先把三個(gè)參數(shù)收集起來,然后到最后再調(diào)用第一種寫法的函數(shù):
function sum3(x) { return function(y) { return function(z) { return _sum3(x, y, z) } } } console.log(sum3(1)(2)(3)) // 6
所以柯里化的寫法只是把常用寫法包裝了一下,可以使用一個(gè)專用的柯里化函數(shù)實(shí)現(xiàn)這種包裝??吕锘瘮?shù)是一種高階函數(shù),我們把它命名為curry
function curry(fn) { return function(y) { return function(z) { return fn(x, y, z) } } } var sum3 = curry((x, y, z) => { return x + y + z }) console.log(sum3(1)(2)(3)) // 6
如果有要寫一種更加通用的,可以柯里化擁有任意多個(gè)參數(shù)的函數(shù)呢,比如sumN(1)(2)(3)...(N),按照之前的寫法,大概是這個(gè)樣子的:
function curryN(fn) { return function(a1) { return function(a2) { return function(a3) { //...... return function(aN) { return fn(a1, a2, a3, ...aN) } } } } }
很容易想到可以用一個(gè)遞歸函數(shù)來簡(jiǎn)化這種寫法,將上面那些看起來相似的函數(shù)結(jié)構(gòu)命名為nest,就可以寫為:
function nest(fn) { return function(x) { return nest(fn) } } function curry(fn) { nest(fn) }
這里缺少一個(gè)循環(huán)終止的判斷,所以nest函數(shù)先引入一個(gè)新參數(shù)i,當(dāng)i === N時(shí)遞歸終止
function nest(fn, i) { return function(x) { if (i === N) { return fn(...) } return nest(fn, i + 1) } } function curry(fn) { return nest(fn, 1) }
接著,需要一個(gè)存放任意多個(gè)參數(shù)的數(shù)組,將這個(gè)數(shù)組命名為args,然后傳入nest函數(shù)
function nest(fn, i, args) { return function(x) { args.push(x) if (i === fn.length) { return fn(...args) } return nest(fn, i + 1, args) } } function curry(fn) { const args = [] return nest(fn, 1, args) }
最后在添加一個(gè)處理0個(gè)參數(shù)的情況,我們就完成了最終版的柯里化函數(shù)
function curry(fn) { if (fn.length === 0) { return fn } const args = [] return nest(fn, 1, args) }
測(cè)試一下,在線demo:
const log1 = curry((x) => console.log(x)) log1(10) // 10 const mul3 = curry((x, y, z) => console.log(x*y*z)) mul3(2)(3)(4) // 24參考文章
Currying in JS
Currying in JavaScript ES6
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/94318.html
摘要:組合的概念是非常直觀的,并不是函數(shù)式編程獨(dú)有的,在我們生活中或者前端開發(fā)中處處可見。其實(shí)我們函數(shù)式編程里面的組合也是類似,函數(shù)組合就是一種將已被分解的簡(jiǎn)單任務(wù)組織成復(fù)雜的整體過程。在函數(shù)式編程的世界中,有這樣一種很流行的編程風(fēng)格。 JavaScript函數(shù)式編程,真香之認(rèn)識(shí)函數(shù)式編程(一) 該系列文章不是針對(duì)前端新手,需要有一定的編程經(jīng)驗(yàn),而且了解 JavaScript 里面作用域,閉...
摘要:原文鏈接和都支持函數(shù)的柯里化函數(shù)的柯里化還與的函數(shù)編程有很大的聯(lián)系如果你感興趣的話可以在這些方面多下功夫了解相信收獲一定很多看本篇文章需要知道的一些知識(shí)點(diǎn)函數(shù)部分的閉包高階函數(shù)不完全函數(shù)文章后面有對(duì)這些知識(shí)的簡(jiǎn)單解釋大家可以看看什么是柯里化 原文鏈接 Haskell和scala都支持函數(shù)的柯里化,JavaScript函數(shù)的柯里化還與JavaScript的函數(shù)編程有很大的聯(lián)系,如果你感興...
摘要:柯里化通用式上面的柯里化函數(shù)沒涉及到高階函數(shù),也不具備通用性,無法轉(zhuǎn)換形參個(gè)數(shù)任意或未知的函數(shù),我們接下來封裝一個(gè)通用的柯里化轉(zhuǎn)換函數(shù),可以將任意函數(shù)轉(zhuǎn)換成柯里化。 showImg(https://segmentfault.com/img/remote/1460000018998373); 閱讀原文 前言 在 JavaScript 中,柯里化和反柯里化是高階函數(shù)的一種應(yīng)用,在這之前...
摘要:閱讀學(xué)習(xí)專題之函數(shù)柯里化函數(shù)式編程指南對(duì)柯里化的理解很多人對(duì)于柯里化的理解僅僅停留在復(fù)用參數(shù)上。使用柯里化的場(chǎng)景想要實(shí)現(xiàn)某個(gè)操作邏輯。換句話說,柯里化將輸入的函數(shù)和參數(shù)進(jìn)行綁定,返回綁定后的函數(shù),返回的函數(shù)期待剩余的參數(shù)。 閱讀學(xué)習(xí) JavaScript專題之函數(shù)柯里化JS 函數(shù)式編程指南 對(duì)柯里化的理解 很多人對(duì)于柯里化的理解僅僅停留在復(fù)用參數(shù)上。但我認(rèn)為函數(shù)式編程思想更重要作用的是...
摘要:原題如下寫一個(gè)方法,當(dāng)使用下面的語法調(diào)用時(shí),能正常工作這道題要考察的,就是對(duì)函數(shù)柯里化的理解。當(dāng)參數(shù)只有一個(gè)的時(shí)候,進(jìn)行柯里化的處理。這其實(shí)就是函數(shù)柯里化的簡(jiǎn)單應(yīng)用。 showImg(https://segmentfault.com/img/bVbopGm?w=620&h=350); 前言 這是前端面試題系列的第 6 篇,你可能錯(cuò)過了前面的篇章,可以在這里找到: ES6 中箭頭函數(shù)的...
閱讀 2937·2021-11-23 09:51
閱讀 3109·2021-11-15 11:39
閱讀 2992·2021-11-09 09:47
閱讀 2538·2019-08-30 13:49
閱讀 2122·2019-08-30 13:09
閱讀 3107·2019-08-29 16:10
閱讀 3511·2019-08-26 17:04
閱讀 998·2019-08-26 13:57