js 函式的柯里化 Currying

2022-03-16 11:18:29 字數 2827 閱讀 4373

1. 詳解js函式柯里化 ;

2. 函式式編的js: curry ;

維基百科上說道:柯里化,英語:currying(果然是滿滿的英譯中的既視感),是把接受多個引數的函式變換成接受乙個單一引數(最初函式的第乙個引數)的函式,並且返回接受餘下的引數而且返回結果的新函式的技術。  

舉例:

// 普通的add函式

function multiply(x, y)

// currying 前的呼叫

multiply(3, 4) // 12

multiply(3, 5) // 15

multiply(3, 6) // 16

經過 currying(偽) 後

function multiply(x)

}multiply(3)(4) // 12

實際上就是把add函式的x,y兩個引數變成了先用乙個函式接收x然後返回乙個函式去處理y引數。現在思路應該就比較清晰了,就是只傳遞給函式一部分引數來呼叫它,讓它返回乙個函式去處理剩下的引數。

這裡的優點以及**基本搬運自資料 1 中內容。

1. 引數復用

// 正則驗證字串 reg.test(txt);

// 很符合我們寫業務**的習慣

function check(reg, txt)

check(/\d+/g, 'test') //false

check(/[a-z]+/g, 'test') //true

// curry 後

function curringcheck(reg)

}// 中間函式, 預先設定規則

var hasnumber = curryingcheck(/\d+/g)

var hasletter = curryingcheck(/[a-z]+/g)

// 這樣,想做哪種檢測,直接呼叫中間函式即可,不需要每次都傳入規則

hasnumber('test1') // true

hasnumber('testtest') // false

hasletter('21212') // false

// es 6 的簡便寫法, 這裡先用稍微用下下面的內容

// 其中, fn 是待 currying 的函式, curry 是工具函式

let curry = (fn) => (farg) => (sarg) => fn(farg, sarg);

2. 提前確認(這一條更多的是用到了閉包)

// 原**

var on = function(element, event, handler)

} else

}}// 自執行函式形成閉包

var on = (function ()

}} else }}

})();

// 換一種寫法可能比較好理解一點,上面就是把issupport這個引數給先確定下來了

var on = function(issupport, element, event, handler) else

}

3. 延遲執行(感覺也是閉包啊)

function.prototype.bind = function(context) 

}

1. 單層

var currying = function(fn) 

}

2. 多層 (遞迴,適合 fn(.)(.)(.)(.)... 的形式)

三層寫法核心思路是一致的。

// 寫法 1, 支援多引數傳遞

function currying(fn, args)

}}// 寫法 2

let currying = (fn, type = ) => else

}}// 寫法 3

// 多了層匿名函式, 用來蒐集傳入的引數

let curry = fn => }}

}

主要在效能上:

1. 由於使用了閉包, 閉包該有的問題乙個不落地全部繼承;

2.(如果有) 訪問 arguments 物件通常要比訪問命名引數要慢一點;

3.(如果有) 一些老版本的瀏覽器在 arguments.length 的實現上是相當地慢;

不過相對於頻繁的 dom 操作, currying 到來的效能消耗可以忽略不計。

currying 函式在設計上第一次呼叫必須傳入乙個函式,這是它的使用原則。

另外, 如果原函式的引數 > 2 ( fn(x, y, z, m, n, ...) )的話, 多層寫法中的 2 & 3 是支援 curry(fn)(x)(y, z)(m)(n)(...) 這種寫法的。

下面這條題目作為拓展:

// 實現乙個add方法,使計算結果能夠滿足如下預期:

add(1)(2)(3) = 6;

add(1, 2, 3)(4) = 10;

add(1)(2)(3)(4)(5) = 15;

function add() ;

// 利用tostring隱式轉換的特性,當最後執行時隱式轉換,並計算最終的值返回

_adder.tostring = function () );

}return _adder;

}add(1)(2)(3) // 6

add(1, 2, 3)(4) // 10

add(1)(2)(3)(4)(5) // 15

add(2, 6)(1) // 9

js函式柯里化

什麼是函式柯里化?在電腦科學中,柯里化 currying 是把接受多個引數的函式變換成接受乙個單一引數 最初函式的第乙個引數 的函式,並且返回接受餘下的引數且返回結果的新函式的技術。這個技術由 christopher strachey 以邏輯學家 haskell curry 命名的,儘管它是 mos...

js 函式柯里化

函式柯里化的主要目的就是為了減少函式傳參,同時將一些固定引數私有化。下面展示一段非常簡單計算圓面積的 來說明函式柯里化的原理 circle函式,接受半徑r和 function circle r,p 通過函式柯里化來簡化circle函式,只傳入半徑就能計算出面積 不管怎麼樣,是不會變的,因此我們將他寫...

js 函式柯里化

函式柯里化的主要目的就是為了減少函式傳參,同時將一些固定引數私有化。下面展示一段非常簡單計算圓面積的 來說明函式柯里化的原理 circle函式,接受半徑r和 function circle r,p 通過函式柯里化來簡化circle函式,只傳入半徑就能計算出面積 不管怎麼樣,是不會變的,因此我們將他寫...