JS的Currying
来源:互联网 发布:极光推送 php接口实例 编辑:程序博客网 时间:2024/06/10 00:55
那么到底什么是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实现,一个简单的求和函数:
return x + y;
}
console.log('add(2, 3) == ' + add(2, 3));
对其进行Currying,及调用方法:
return function(y) {
return x + y;
}
}
console.log('curry_add(2)(3) == ' + curry_add(2)(3));
注意,curry_add(2) 返回的是函数。
我们还可以定义一个通用的 curry 函数:
var args = [];
for (var i = 1; i < arguments.length; i++) {
args.push(arguments[i]);
}
return function() {
for (var i = 0; i < arguments.length; 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)());
因为 curry(add, 2) 或 curry(add) 返回的还是函数,所以我们还可以对其进行Currying,如下代码:
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
这就好办了,我们可以根据传递进来的参数的多少来判断是否返回执行结果或者是返回函数。
我大概的想法是要用到递归,来看看我的实现:
var args = [];
for (var i = 1; i < arguments.length; i++) {
args.push(arguments[i]);
}
return function() {
for (var i = 0; i < arguments.length; 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技术:
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的实现代码:
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 );
- JS的Currying
- 什么是js函数的currying /柯里化?
- currying in javascript-js柯里化
- Currying
- Javascript中currying的实现
- Javascript currying的三种实现
- 函数Currying和Partial Application的比较
- 对Javascript柯里化currying的理解
- Scala Learning(4): Currying柯里化的推演
- Scala Currying
- Currying是什么
- scala Currying
- 函数加里化(Currying)和偏函数应用(Partial Application)的比较
- 函数加里化(Currying)和偏函数应用(Partial Application)的比较
- 函数式编程中局部应用(Partial Application)和局部套用(Currying)的区别
- 深入理解scala的柯里化( currying or curry )以及其用处
- javascript科里化(Currying)
- 柯里化(Currying)
- Android中自定义Activity和Dialog的位置大小背景和透明度等
- js详解
- windows程序设计 例题解析 NOPOPUPS.C
- 进程原语和线程原语的比较
- 《五种算法以后》
- JS的Currying
- 在vb里谁知道shift,ctrl和alt,F1怎么表示?
- 使用Tomcat7自带的数据库连接池
- 内存映射
- 海量存储之一
- jbpm5 介绍
- CentOS6.2搭建使用Radius认证的OpenVPN
- 计算机专业就业分析
- Wireshark学习总结