组合函数定义

组合函数是纯函数衍生出来的一种函数,把一个纯函数的结果做为另一个纯函数的输入,最终得到一个新的函数,就是组合函数,组合函数是从右到左的数据流,例如

const compose = (f1, f2) => value => f1( f2(value) );

举个例子,我们需要实现一个 fullname 的功能

function connect(firstName, lastName) {
  return firstName + lastName;
}

function toUpperCase(name) {
  return name.toUpperCase()
}

把上面两个函数组合起来就变成了下面的函数,叫做组合函数

function fullname(firstName, lastName) {
  return toUpperCase(connect(firstName, lastName))
}
fullname('huang', 'kailun')

这个只是一个简单的例子,为了说明把多个功能函数组合成一个更高级功能的函数。

组合函数转换器

上面的例子是两个纯函数的组合,如果是多个函数的组合(比如f, f1, f2, f3),类似于下面的组合,就会变得很恶心

function componse(...args) {
  return f(f2(f3(f4(...args))))
}

这时候就需要一种组合函数转换器,通过传递函数数组来自动帮我们转为成组合函数,结构类似于

const componse = (...functions) => (...args) => { 
  // 转换操作
  return newFunction
}

Javascript给数组对象提供了一个 reduceRight() 方法,接收一个函数作为累加器,数组从右到左开始缩减,最终计算为一个值,使用如下

[1, 2, 3].reduceRight((prev, curr) { return prev + curr }, 0) // 6

我们可以利用 reduceRight 这一个特性来实现组合函数转换器

const componse = (...fns) => fns.reduceRight((pFn, cFn) => (...args) => cFn(pFn(...args)))

测试效果

// 新增一个hello函数
function hello(name) {
  return `hello ${name}`
}
const sayHello = componse(hello, toUpperCase, connect)
console.log(sayHello('huang', 'kelen')) // hello HUANG KAILUN