Javascript函数柯里化(curry)
函数柯里化currying,是函数式编程非常重要的一个标志。它的实现需要满足以下条件,首先就是函数可以作为参数进行传递,然后就是函数可以作为返回值return出去。我们依靠这个特性编写很多优雅酷炫的代码。那我们来看一下最简单的实现。
大家一般都是举addSum的例子,我当然也不例外。
add = (num1)->
return (num2)->
return num1 + num2;
add3 = add(3);
add5 = add(5);
add3(5) # 返回8
add5(5) # 返回10
上述例子其实已经对柯里化的实现,有一个非常好的了解了。其实也就是“分步求值”,我们可以把第一个参数通过闭包保存起来,以供return出去的匿名函数使用。所以我们可以根据add来自定义各种各样的新函数。
我们要使某个函数可以柯里化,难道一定要在函数创建时,就具有柯里化的特性么?假设我们的add函数,起初并不具有柯里化特性的,我们需要怎么做才能让它柯里化呢?
add = (num1, num2)->
return num1 + num2;
curry = (fn)->
args = [].slice.call(arguments, 1);
return ()->
[].push.apply(args, arguments);
return fn.apply(this, args);
add5 = curry(add, 5)
add5(3) # 返回8
原理还是一样的,我们通过curry函数,让fn需要的第一次的参数通过闭包保存在args的变量里,以供匿名函数使用。最后结合第二次需要的参数,使用apply一次性导入args,完成操作。
上述我们看到的都是分两步求值,这其实并不符合我们更丰富的实际需求。我们需要考虑如何才可以将函数柯里化变成我们需要的想分步便分步,想停止便停止呢?
首先我们需要约定一个规则,这个规则和大部分的Getter/Setter方法一样。当函数没有参数时,执行的是Getter,而有参数的话,则是执行“Setter”。(这个也是Javascript实现简陋的函数重载的一种方法)
curry = (fn)->
args = [];
return ()->
if arguments.length == 0
return fn.apply(this, args);
else
[].push.apply(args, arguments);
return arguments.callee;
addSum = ()->
sum = 0;
for num in arguments
sum += num;
return sum;
currySum = curry(addSum);
currySum(1, 2, 3);
currySum(1);
currySum(1);
currySum(1);
currySum(1);
currySum(); # 返回 10
实现原理其实也很简单,通过闭包,将每次的参数保存在args数组了。当不传参执行Getter时,就直接通过apply函数,将数组参数导入。我们只需要在addSum函数那里处理好导入的参数数组即可。
更多的柯里化带来的妙处,则需要你在实际使用中,细细品味。相信一旦你掌握了这个灵活可靠的方法,可以为你带来不一样的感受。
Javascript函数柯里化(curry)的更多相关文章
- JavaScript函数柯里化的一些思考
1. 高阶函数的坑 在学习柯里化之前,我们首先来看下面一段代码: var f1 = function(x){ return f(x); }; f1(x); 很多同学都能看出来,这些写是非常傻的,因为函 ...
- Scala 基础(十二):Scala 函数式编程(四)高级(二)参数(类型)推断、闭包(closure)、函数柯里化(curry)、控制抽象
1 参数(类型)推断 参数推断省去类型信息(在某些情况下[需要有应用场景],参数类型是可以推断出来的,如list=(1,2,3) list.map() map中函数参数类型是可以推断的),同时也可以 ...
- JavaScript函数柯里化
函数式 JavaScript是以函数为一等公民的函数式语言.函数在JavaScript中也是一个对象(继承制Function),函数也可以作为参数传递成函数变量.最近几年函数式也因为其无副作用的特性. ...
- 函数柯里化 curry
一.函数柯里化的特性: (1)参数复用 $.ajax // 示例一 function ajax(type,url,data) { var xhr = new XMLHttpRequest(); xhr ...
- javascript函数柯里化初探
// 柯里化之前 function add(x,y,z){ return x+y+z; } add(1,2,3) // 6 // 柯里化之后 function curryAdd(x){ return ...
- 深入理解javascript函数进阶系列第二篇——函数柯里化
前面的话 函数柯里化currying的概念最早由俄国数学家Moses Schönfinkel发明,而后由著名的数理逻辑学家Haskell Curry将其丰富和发展,currying由此得名.本文将详细 ...
- 前端进击的巨人(五):学会函数柯里化(curry)
柯里化(Curring, 以逻辑学家Haskell Curry命名) 写在开头 柯里化理解的基础来源于我们前几篇文章构建的知识,如果还未能掌握闭包,建议回阅前文. 代码例子会用到 apply/call ...
- 简单粗暴详细讲解javascript实现函数柯里化与反柯里化
函数柯里化(黑人问号脸)???Currying(黑人问号脸)???妥妥的中式翻译既视感:下面来一起看看究竟什么是函数柯里化: 维基百科的解释是:把接收多个参数的函数变换成接收一个单一参数(最初函数的第 ...
- JavaScript中的事件循环机制跟函数柯里化
一.事件循环机制的理解 test();//按秒输出5个5 function test() { for (var i = 0; i < 5; i++) { setTimeout(() => ...
随机推荐
- Linux 查看端口占用并杀掉
1. 查看端口号占用情况: netstat -apn|grep 80 tcp 0 0 10.65.42.27:80 172.22.142.20:627 ...
- binary-tree-maximum-path-sum(mock)
注意: // 注意,如果一个类放在另一个类里面,初始化时候会报错 Solution is not a enclosing class// 这是因为如果TreeNode不是static,那么要求先有外部 ...
- 如何停止Android Monkey脚本
如何停止Android Monkey脚本 最近用monkey来包apk的性能测试,发现一旦monkey跑起来以后,即使将数据线和PC断开,monkey脚本还是会继续运行下去.结果找到了一个办法去停止它 ...
- 【温故知新】C#委托delegate
在c#的学习过程中,学到委托与事件总会迷糊一段时间,迷糊过后自然而就似懂非懂了~,所以最近我打算把以前所学的迷糊过的知识总结,温故知新,总结记录下来. 首先,我们来看一下msdn对委托的定义: del ...
- java.util.logging.Logger使用详解
一.创建Logger对象 static Logger getLogger(String name) 为指定子系统查找或创建一个 logger. static Logger ge ...
- jQuery小例子
map遍历数组 //=========for循环遍历========== var arr[1,2,3,4,5]; for(var i=0;i<=arr.length;i++) { arr[i]= ...
- 解决iis出现这个问题-2147467259 (0x80004005)
在运行中运行下面命令就可解决问题 regsvr32 vbscript.dllregsvr32 jscript.dllregsvr32 %windir%\system32\inetsrv\asp.dll
- js二级下拉被flash档住的解决办法
在<object></object>及以内的代码加入到<script>标签对内 <script language="javascript" ...
- 决策树之 CART
继上篇文章决策树之 ID3 与 C4.5,本文继续讨论另一种二分决策树 Classification And Regression Tree,CART 是 Breiman 等人在 1984 年提出的, ...
- [原创] Ubuntu Linux 安装Eclipse
一 安装JDK 1.下载 JDK 7从http://www.oracle.com/technetwork/java/javasebusiness/downloads/选择下载JDK的最新版本 JDK ...