compose函数
compose函数
在学习redux源码的时候看到了其中的工具函数compose,compose函数的作用就是组合函数,依次组合传入的函数:
- 后一个函数作为前一个函数的参数
- 最后一个函数可以接受多个参数,前面的函数只能接受单个参数;后一个的返回值传给前一个
reduce实现
redux中是使用reduce
实现的
function compose(...funcs) {
//没有传入函数参数,就返回一个默认函数(直接返回参数)
if (funcs.length === 0) {
return arg => arg
}
if (funcs.length === 1) {
// 单元素数组时调用reduce,会直接返回该元素,不会执行callback;所以这里手动执行
return funcs[0]
}
// 依次拼凑执行函数
return funcs.reduce((a, b) => (...args) => a(b(...args)))
}
reduce的详细说明可以查阅MDN。
举例分析:compose(f4,f3,f2,f1)(c,d,e)
- reduce回调函数第一次执行时,返回值为 函数
(...args) => f4(f3(...args))
,作为下一次执行的a参数 - 回调函数第二次执行时,返回值为 函数
(...args) => f4(f3(f2(...args)))
,作为下一次执行的a参数 - 回调函数第三次执行时,返回值为 函数
(...args) => f4(f3(f2(f1(...args))))
最右边的参数f1
可以接受多个参数,然后返回结果传给下一个函数f2
,返回结果再传入f3
··· f3
最先被调用,会等待f2
的结果,再等待f1
的结果。
let a = (x,y) => x + y,
b = x => x * x,
c = x => x === 0 ? x : 1/x;
compose(c,b,a)(1,2); // 1/9
那么如果想从左到右返回结果呢?
- 使用
reduceRight
- 将
funcs
倒序
迭代实现
用迭代的方式实现从右到左依次执行的组合函数。
function compose(...funcs) {
let length = funcs.length;
return function(...arg) {
let index = length - 1,
result = length > 0 ? funcs[index].apply(this,arg) : arg; //注意arg为数组,要用apply
while(--index >=0 ) {
result = funcs[index].call(this,result);
}
return result;
}
}
通过index
来标记应该执行哪个函数,这里是从最右边(length - 1
)开始执行的,每执行一个index
就减1,直到index
为0
(最左边)为止。
用result
来记录每次函数执行的返回值,每次都会更新,直到所有函数都执行完。才会返回最终结果
如果传递的函数列表为空,则返回传入参数。
同样的如果需要从左到右依次执行,则将funcs
倒序即可。
compose函数的更多相关文章
- JS高阶编程技巧--compose函数
先看代码: let fn1 = function (x) { return x + 10; }; let fn2 = function (x) { return x * 10; }; let fn3 ...
- compose 函数实现
总结componse函数实现过程 大致特点 参数均为函数, 返回值也是函数 第一函数接受参数, 其他函数接受的上一个函数的返回值 第一个函数的参数是多元的, 其他函数的一元的 自右向左执行 简单实现 ...
- C#函数式编程之由函数构建函数
在面向对象的编程中,如果我们需要复用其他的类,我们可以通过继承来实现.而在函数式编程中我们也可以采取不同的方式来复用这些函数.今天的教程将会讲述两种方式,其中一个就是组合,将多个函数组合成为一个函数, ...
- JavaScript函数柯里化的一些思考
1. 高阶函数的坑 在学习柯里化之前,我们首先来看下面一段代码: var f1 = function(x){ return f(x); }; f1(x); 很多同学都能看出来,这些写是非常傻的,因为函 ...
- 函数式编程-compose与pipe
函数式编程中有一种模式是通过组合多个函数的功能来实现一个组合函数.一般支持函数式编程的工具库都实现了这种模式,这种模式一般被称作compose与pipe.以函数式著称的Ramda工具库为例. cons ...
- javascript基础修炼(8)——指向FP世界的箭头函数
一. 箭头函数 箭头函数是ES6语法中加入的新特性,而它也是许多开发者对ES6仅有的了解,每当面试里被问到关于"ES6里添加了哪些新特性?"这种问题的时候,几乎总是会拿箭头函数来应 ...
- javascript柯里化及组合函数~
大家是不是看我上篇博文有点蒙.用的的curry和compose是什么鬼,怎么那么神奇.上篇博文也是主要用到了这两个函数.那今天我们来聊一下curry和compose,这两个东西是函数式编程很重要的东西 ...
- js函数式编程(三)-compose和pointFree
compose即函数嵌套组合 组合compose在第一篇已经初见端倪,可以感受一下.compose函数的实现用闭包的方法.不完善实现如下: const compose = (f, g) => { ...
- 高阶函数&&高阶组件(二)
高阶组件总共分为两大类 代理方式 操纵prop 访问ref(不推荐) 抽取状态 包装组件 继承方式 操纵生命周期 操纵prop 代理方式之 操纵prop 删除prop import React fro ...
随机推荐
- 常用的三种json软件的使用
从几个角度比较三种软件 1. json操作 2 反解 3 性能 易用性还没有列出. 可以根据个人喜好进行取舍. package json; import com.alibaba.fastjson.JS ...
- node.js 使用NAPI写C++插件,(部分转帖)
原文:https://www.cnblogs.com/chyingp/p/nodejs-learning-napi.html 可能是版本问题,我用node v10.6.0 遇到了问题 不过解决了. 一 ...
- 面试简单整理之rabbitmq
135.rabbitmq 的使用场景有哪些? 单反单收,单发多收,发布订阅,按路由发送,按主题发送 136.rabbitmq 有哪些重要的角色? Server,Consumer,Producer 13 ...
- mysql约束以及数据库的修改
一.约束 1.约束保证数据完整性和一致性. 2.约束分为表级约束和列级约束. (1)表级约束(约束针对于两个或两个以上的字段使用) (2)列级约束(针对于一个字段使用) 3.约束类型有: (1)NOT ...
- jira6.3.6创建问题不自动发邮件通知的问题
装完jira6.3.6后,设置好邮件服务器,测试没有问题.但是创建问题不自动发邮件提示用户.折腾了大半天,请教了一位大神,终于搞定.步骤是: agile->系统->用户界面->用户缺 ...
- JS require and import
作者:寸志链接:https://www.zhihu.com/question/56820346/answer/150724784来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明 ...
- logstash 默认时间少8小时的修改办法
logstash 的配置文件添加 filter { ruby { code => "event.set('timestamp', event.get('@timestamp').tim ...
- dom4j移除节点不成功
在使用dom4j的时候想移除xml节点,经常使用remove来移除节点,通过整个文档或者根节点删除某一个子节点,但如果子节点不是儿子节点,在dom4j中就无法删除.在dom4j中移除节点必须使用父节点 ...
- ELK的高级篇(测试记录各种日志)
一.elk架构已经完成情况情况下 访问限制: 加个x-pack插件 1)一个脚本收集多个日志,if 判断写入es的索引 [root@k8s6 conf.d]# cat file.conf inpu ...
- 使用vmware vconverter从物理机迁移系统到虚拟机P2V(多图)
zhuan:https://segmentfault.com/a/1190000002697929 本文完整记录了如何从物理服务器,保持所有环境配置信息,纹丝不动的迁移到虚拟机上,俗称 P2V .采用 ...