Javascript中currying的實現
Currying好像是函式式語言都有的一個特性,比如Perl,Python,Javascript。
那麼到底什麼是Currying,我是在學習Closure時無意中接觸到這個定義的,覺得很是有趣。
先看看 Wiki 中的定義:
Currying is the technique of transforming a function that takes multiple arguments
in such a way that it can be called as a chain of functions each with a single argument.
大概的意思就是說,將擁有多個引數的函式Currying化為擁有單一引數的函式形式。
下面舉一個簡單的例子說明Javascript中的Currying實現,一個簡單的求和函式:
function add(x, y) {
return x + y;
}
console.log('add(2, 3) == ' + add(2, 3));
對其進行Currying,及呼叫方法:
function curry_add(x) {
return function(y) {
return x + y;
}
}
console.log('curry_add(2)(3) == ' + curry_add(2)(3));
注意,curry_add(2) 返回的是函式。
我們還可以定義一個通用的 curry 函式:
function curry(fn) {
var args = [];
for (var i = 1; i args.push(arguments[i]);
}
return function() {
for (var i = 0; i args.push(arguments[i]);
}
return fn.apply(window, args);
}
}
這個函式至少接收一個引數(需要curry的函式),對於前面的 add 函式,我們可以這樣來呼叫:
console.log('curry(add)(2, 3) == ' + curry(add)(2, 3));
console.log('curry(add, 2)(3) == ' + curry(add, 2)(3));
console.log('curry(add, 2, 3)() == ' + curry(add, 2, 3)());
因為 curry(add, 2) 或 curry(add) 返回的還是函式,所以我們還可以對其進行Currying,如下程式碼:
console.log('curry(curry(add), 2)(3) == ' + curry(curry(add), 2)(3));
console.log('curry(curry(add, 2), 3)() ==' + curry(curry(add, 2), 3)());
執行時截圖:
程式碼下載
[update_2009-2-17]
按照 @winter-cn 的提示,我來到另外一篇討論Currying的 文章 ,發現那裡的做法是寫一個可以 Chain 的Currying,
另外我還發現了一個我以前不知道的特性,add.length 返回的是函式形式引數的個數,比如這個例子中的 add.length == 2
這就好辦了,我們可以根據傳遞進來的引數的多少來判斷是否返回執行結果或者是返回函式。
我大概的想法是要用到遞迴,來看看我的實現:
function curry2(fn) {
var args = [];
for (var i = 1; i args.push(arguments[i]);
}
return function() {
for (var i = 0; i args.push(arguments[i]);
}
if (args.length >= fn.length) {
return fn.apply(window, args);
}
else {
return curry2.apply(window, [fn].concat(args));
}
}
}
console.log('curry2(add)(2, 3) == ' + curry2(add)(2, 3));
console.log('curry2(add)(2)(3) == ' + curry2(add)(2)(3));
當然這樣的Currying技術,只能用在有明確形式引數的函式中,如果在add函式中使用arguments來捕獲引數,則這種Currying是行不通的。
上面的add可能不是很明顯,來看看擁有 4 個引數的add2函式,以及使用Currying技術:
function add2(x, y, z, k) {
return x + y + z + k;
}
console.log('curry2(add2)(1, 2, 3, 4) == ' + curry2(add2)(1, 2, 3, 4));
console.log('curry2(add2)(1, 2, 3)(4) == ' + curry2(add2)(1, 2, 3)(4));
console.log('curry2(add2)(1, 2)(3, 4) == ' + curry2(add2)(1, 2)(3, 4));
console.log('curry2(add2)(1)(2, 3, 4) == ' + curry2(add2)(1)(2, 3, 4));
console.log('curry2(add2)(1)(2)(3, 4) == ' + curry2(add2)(1)(2)(3, 4));
console.log('curry2(add2)(1)(2)(3)(4) == ' + curry2(add2)(1)(2)(3)(4));
更新的程式碼下載
附:John Resig在Pro Javascript一書中關於Currying的實現程式碼:
// A function that generators a new function for adding numbers
function addGenerator( num ) {
// Return a simple function for adding two numbers
// with the first number borrowed from the generator
return function( toAdd ) {
return num + toAdd
};
}
// addFive now contains a function that takes one argument,
// adds five to it, and returns the resulting number
var addFive = addGenerator( 5 );
// We can see here that the result of the addFive function is 9,
// when passed an argument of 4
alert( addFive( 4 ) == 9 );
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/2730/viewspace-2800202/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Js中Currying的應用JS
- Javascript currying柯里化詳解JavaScript
- javascript中的hashtable實現JavaScript
- JavaScript中getter/setter的實現JavaScript
- javascript中的觀察者模式實現JavaScript模式
- JavaScript中new實現原理JavaScript
- Javascript中裝飾器的實現原理JavaScript
- JavaScript 中實現等分陣列JavaScript陣列
- JavaScript中的繼承及實現程式碼JavaScript繼承
- java如何實現javascript中的eval函式JavaScript函式
- JavaScript中模擬實現jsonpJavaScriptJSON
- 【乾貨理解】理解javascript中實現MVC的原理JavaScriptMVC
- Swift3.0 CurryingSwift
- javascript實現的任意擷取字串中的子字串JavaScript字串
- JavaScript 實現全部選中與全不選JavaScript
- Javascript 中實現物件原型繼承的三種方式JavaScript物件原型繼承
- 在 JavaScript 中實現私有成員的語法特性JavaScript
- Git 的 JavaScript 實現 GitletGitJavaScript
- Javascript 實現的StopWatchJavaScript
- javascript的hashCode實現JavaScript
- 字典(Dictionary)的javascript實現JavaScript
- JavaScript 中如何實現函式佇列?(一)JavaScript函式佇列
- JavaScript實現《啊哈!演算法》中的系列演算法JavaScript演算法
- javascript中的匯出和匯入實現模組化管理JavaScript
- JavaScript 函數語言程式設計中的 curry 實現JavaScript函數程式設計
- 細節解析 JavaScript 中 bind 函式的模擬實現JavaScript函式
- 【JavaScript框架封裝】JavaScript中的文字字串的轉義和反轉義的實現JavaScript框架封裝字串
- JavaScript Ajax 實現JavaScript
- JavaScript中變數提升是什麼?如何實現?JavaScript變數
- javascript模擬new的實現JavaScript
- JavaScript 模擬new的實現JavaScript
- JavaScript 差量更新的實現JavaScript
- JavaScript實現繼承的方式JavaScript繼承
- javascript如何實現類的功能JavaScript
- Javascript – Arraylike的7種實現JavaScript
- 快速排序(Quicksort)的Javascript實現排序UIJavaScript
- 介面卡在JavaScript中的體現JavaScript
- 高階函式應用--currying函式