pipe函数与compose函数
pipe函数与compose函数
转眼间自己写代码已经两年了,这期间从刚开始的什么都不会,到会写一些页面,在到可以熟练的写一些业务代码。几乎每天都是拼凑,对于小的项目已经简单的业务来说没什么问题,但随着时间的流逝,业务变得越来越复杂,代码体积越来越庞大,随之而来的bug也就越多。
出于一个程序员的本能,开始对软件架构有一些思想,并开始学习。
最近有接触到两个函数一个是pipe函数一个compose函数,下面来分享一下
什么是compse函数
compose函数就是,就是可以把一些函数串联起来,第一个函数返回值作为后一个函数的参数,依次执行。
在我们编码的过程中,我们可以将复杂的逻辑拆解为简单的运算单元。然后通过这些运算的单元的拼凑,可以实现复杂的运算。从而做到,每一个运算单元可以有单一职责,单元跟单元之间互相没有关系。对于整体运算更加具有语义化。
举个例子
/**
* 实现一个函数,计算x * 2 / 3 + 4 - 5的结果
*/// 我们普通是想法function cal(x) {
return typeof x === 'number' ? x * 2 / 3 + 4 - 5 :x
}
首先, 上面的写法是没有问题的,可以实现我们的需求。
但是,这种代码是比较典型命令式编程,可扩展性与可复用性更差。
下面我们对他进行拆分实现可以函数有更好的可复用性
// 为了提高代码的复用性我们进行拆分
// 首先我们来定义我们的基本运算
function add(n) {
return n + 4
}function sub(n) {
return n - 5
}function mul(n) {
return n * 2
}function division(n) {
return n / 3
}// 最终的函数, 大功告成
function cal(x) {
return sub(add(division(mul(x))))
}
上面的方法看起来确实,把之前的运算逻辑做了一些拆分,但是最终我们得到的函数,仍然显得比较丑陋,特别是当面对很长的函数命名时,胃里顿时翻江倒海。
用JavaScript来实现一个compose函数 【pipe函数与compose函数】话不多说直接代码
// 首先compose函数
function compose(a, b, c, d) {
return function(x) {
return d(b(c(a(x))))
}
}// 此处省略我们定义的基本运算函数// 然后我们使用compose函数来实现我们的需求
var cal = compse(mul, division, add, sub)
很不错!看起来好了许多,并且我们通过改变我们传入compse函数的顺序进行不同的运算。
但是,这个我们只能吧运算单元拆分为四个,如果不然就需要写接收更多参数的compse。太坑了!
使用reduce函数 在这里要推出一个重量级选手reduce函数
下面是来自mdn的解释,详细可以查看MDN关于reduce的详细解释
与之相关的有一个函数reduceRight,执行的方向与reduce刚好想反。具体reduce的用法这里不做多余解释。**reduce()**
方法对数组中的每个元素执行一个由您提供的reducer函数(升序执行),将其结果汇总为单个返回值。
兼容性大家可以上caniuse查看,它在新的浏览器上有很好的支持。
下面是使用reduce韩式实现的compse。
function compse() {
// 首先获取参数
var args = [].slice.call(arguments)
// reduceRight从右往左
return args.reduceRight(function(a, b) {
return function(x) {
return a(b(val))
}
})
}var cal= compse(mul, division, add, sub)
这样好了,我们的compose接收的参数数量就不会受限制了,这样的compse函数用途更为广泛。
下面我们使用es6语法实现一遍
const compose = (...args) => {
return x => args.reduceRight((a, b) => x => a(b(x)))
}
对于pipe函数只是计算的顺序刚好相反, 我们将compse函数中的reduceRight替换为reduce即可
代码如下:
const pipe = (...args) => {
return x => args.reduce((a, b) => x => a(b(x)))
}
最后大功告成!谢谢
推荐阅读
- JAVA(抽象类与接口的区别&重载与重写&内存泄漏)
- Docker应用:容器间通信与Mariadb数据库主从复制
- 《真与假的困惑》???|《真与假的困惑》??? ——致良知是一种伟大的力量
- 第326天
- Shell-Bash变量与运算符
- 逻辑回归的理解与python示例
- Guava|Guava RateLimiter与限流算法
- 一起来学习C语言的字符串转换函数
- C语言字符函数中的isalnum()和iscntrl()你都知道吗
- C语言浮点函数中的modf和fmod详解