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(() => ...
随机推荐
- website project team member 角色及开发过程概念图
一个web项目的团队往往具有以下角色的人员组成: project stakeholder(client or business owner)产品经理 Project manager 项目经理 prod ...
- POJ 3211 Washing Clothes【01背包】
题意:给出n种颜色,m件衣服,再分别给出m件衣服的颜色,和洗所需要的时间,dearboy和他的妹子一起洗衣服,且同种颜色的衣服不能同时洗,也不能两个人同时洗一件衣服,问洗完这m件衣服至少需要的时间 先 ...
- 旧书重温:0day2【1】 简单的缓冲区溢出案例
0x01 准备: VMwarePlayer (我是在360软件管家那搜到的下载的) xp sp2 http://user.qzone.qq.com/252738331/blog/1357138598 ...
- Android udev /dev 设备节点权限
/************************************************************************* * Android udev /dev 设备节点权 ...
- 迁移应用数据库到MySQL Database on Azure
by Rong Yu 有用户问怎么把他们应用的数据库迁移到MySQL Database on Azure上,有哪些方式,有没有需要注意的地方.今天我们来概括介绍一下迁移应用数据库到MySQL Data ...
- php排序测试
对 http://www.cnblogs.com/kudosharry/articles/2521621.html 这个补充的调用系统sort()函数的测试结果 1000个随机数: 直接插入排序:时间 ...
- 【转】Github轻松上手5-站在巨人的肩膀上(Fork)
转自:http://blog.sina.com.cn/s/blog_4b55f6860100zzj3.html 有时候你可能想给别人的项目出把力,或者想以别人的项目作为自己项目的起点,在Github里 ...
- CentOS 6.0 缺少 mcrypt 扩展 解决办法
解决办法:安装php-mcrypt libmcrypt libmcrypt-devel这三个库文件 1.安装第三方yum源(默认yum源里面没有这几个库文件,不能使用yum安装) #wget http ...
- java多态中哪些成员具备多态特性
在多态的学习中,当子类继承父类时,子类中的变量哪些具备多态特性,哪些不具备多特特性. 代码: class Father{ public static int x=10; public int y=11 ...
- Android 最火框架XUtils之注解机制详解
http://blog.csdn.net/rain_butterfly/article/details/37931031