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/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Javascript currying柯里化詳解JavaScript
- Js中Currying的應用JS
- JavaScript中new實現原理JavaScript
- Javascript中裝飾器的實現原理JavaScript
- JavaScript 中實現等分陣列JavaScript陣列
- JavaScript中模擬實現jsonpJavaScriptJSON
- JavaScript中的繼承及實現程式碼JavaScript繼承
- JavaScript 實現全部選中與全不選JavaScript
- Javascript 中實現物件原型繼承的三種方式JavaScript物件原型繼承
- 細節解析 JavaScript 中 bind 函式的模擬實現JavaScript函式
- JavaScript實現《啊哈!演算法》中的系列演算法JavaScript演算法
- JavaScript Ajax 實現JavaScript
- javascript模擬new的實現JavaScript
- JavaScript 模擬new的實現JavaScript
- JavaScript 差量更新的實現JavaScript
- JavaScript實現繼承的方式JavaScript繼承
- 【JavaScript框架封裝】JavaScript中的文字字串的轉義和反轉義的實現JavaScript框架封裝字串
- javascript中的匯出和匯入實現模組化管理JavaScript
- JavaScript中變數提升是什麼?如何實現?JavaScript變數
- 實現 JavaScript 沙箱的幾種方式JavaScript
- JavaScript 手動實現instanceof的方法JavaScript
- JavaScript實現淺拷貝的方法JavaScript
- 使用原生javascript實現jquery的$(function(){ })JavaScriptjQueryFunction
- 介面卡在JavaScript中的體現JavaScript
- 原生Javascript實現BindJavaScript
- 實現JavaScript繼承JavaScript繼承
- JavaScript防抖實現JavaScript
- javascript之實現bindJavaScript
- 前端之函式柯里化Currying前端函式
- 如何在 JavaScript 中實現 Event Bus(事件匯流排)JavaScript事件
- JavaScript物件導向—繼承的實現JavaScript物件繼承
- JavaScript資料結構——圖的實現JavaScript資料結構
- JavaScript實現兩個數的交換JavaScript
- JavaScript實現自定義的生命週期JavaScript
- JavaScript之call, apply, bind, new的實現JavaScriptAPP
- [翻譯] 使用JavaScript實現自己的PromisesJavaScriptPromise
- JavaScript 實現 Base64JavaScript
- javascript實現Map結構JavaScript