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(() => ...
随机推荐
- zookeeper监控告警
一.ZooKeeper简介 ZooKeeper作为分布式系统中重要的组件,目前在业界使用越来越广泛,ZooKeeper的使用场景非常多,以下是几种典型的应用场景: l 数据发布与订阅(配置中心) l ...
- JSON 之 SuperObject(3): 访问
测试数据提前加入 Memo1 中: 代码文件: unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, ...
- maven-source 1.3 中不支持注释请使用 -source 5 或更高版本以启用注释
解决办法:在pom里 加上以下代码 <build> <plugins> <plugin> <groupId>org.apache.maven.plugi ...
- jQuery_效果(隐藏和显示)
一.jQuery hide() 显示和 show()隐藏 通过 jQuery,您可以使用 hide() 和 show() 方法来隐藏和显示 HTML 元素: <script type=" ...
- Unable to locate package update
碰到这个问题后找到这个帖子就转了过来 当用apt-get更新软件包时常出现错误提示Unable to locate package update, 尤其是在ubuntu server上,解决方法是: ...
- 如何使用LiveSuite debian img格式的镜像文件刷入nand
1. liveSuite启动后 2. 选择固件(就是对应的img文件) 3. 将cubieboard板子的fel按钮按住不要松,然后使用otg接口线插入电脑和cubieboard板子,直到liveSu ...
- iOS富文本(三)深入使用Text Kit
在上一篇中介绍了Text Kit的三种基本组件的关系并且简单的实现了怎么使用这三种基本组件,本片将深入的去使用这三种基本组件. NSTextStorage NSTextStorage是NSMutabl ...
- 查看mysql存储引擎
一般情况下,mysql会默认提供多种存储引擎,你可以通过下面的查看: 看你的mysql现在已提供什么存储引擎:mysql> show engines; 看你的mysql当前默认的存储引擎:mys ...
- BPMN这点事-BPMN扩展元素
什么是BPMN扩展元素?我们为什么要从BPMN元素中界定出一个扩展元素的子集?BPMN扩展元素是我们平时使用频率不高的BPMN元素,这些元素更多的面向开发人员而不是业务人员,它们强调流程执行的细节,例 ...
- python编码问题(1)
一.字符编码基础 字符编码是计算机对字符的格式化,从而能够在计算机系统中存储与传输. 1.ASCII码 在计算机内部,所有的信息最终都表示为一个二进制的字符串.每一个二进制位(bit)有0和1两种状态 ...