JS函数组合

如果一个功能需要多个细粒度的函数进行组合实现,我们和很容易写出洋葱代码:h(g(f(x)))
例如:获取数组的最后一个元素再转换成大写字母,_.upperCase(_.last(arr))
请添加图片描述
函数组合可以让我们写出这样嵌套的代码

函数组合可以看成城市地下管道

下面这张图表示程序中使用函数处理数据的过程,给 fn 函数输入参数 a,返回结果 b。可以想想 a 数据通过一个管道得到了 b 数据。当 fn 函数比较复杂的时候,我们可以把函数 fn 拆分成多个小函数,此时多了中间运算过程产生的 m 和 n。请添加图片描述
下面这张图中可以想象成把 fn 这个管道拆分成了3个管道 f1, f2, f3,数据 a 通过管道 f3 得到结果 m,m再通过管道 f2 得到结果 n,n 通过管道 f1 得到最终结果 b
请添加图片描述
伪代码

fn = compose(f1, f2, f3)
b = fn(a)

函数组合

如果一个函数要经过多个函数处理才能得到最终值,这个时候可以把中间
过程的函数合并成一个函数

  • 函数就像是数据的管道,函数组合就是把这些管道连接起来,让数据穿过多个管道形成最终结果
  • 函数组合默认是从右到左执行

lodash 的函数组合

我们使用lodash 函数组合方法,将数组最后一个元素大写

var _ = require('lodash');

let arr = ["hcj", 'wcj'];
let compose = _.flowRight(_.upperCase ,_.last);
console.log(compose(arr));

函数组合原理

  1. 接收不固定数量的函数形参,返回一个函数,接受一个参数
  2. 反转函数形参,依次调用,返回结果
let arr = ["hcj", 'wcj'];
function compose(...args) {
    return function(value) {
      return args.reverse().reduce(function(total, fn){
            return fn(total);
        }, value);
    }
}

let composeFn = compose(_.upperCase ,_.last);
console.log(composeFn(arr));

结合律

和数学一样,函数组合也支持结合律

// 结合律(associativity)  ture
let associative = compose(compose(f, g), h) == compose(f, compose(g, h))

调试

在我们使用组合时,如果结果和我们预期不一致,我们如何进行调试?以下面例子来说明:

// NEVER SAY DIE --->   never-say-die
var _ = require('lodash');

let str = "NEVER SAY DIE"
let split = _.curry((sep, str) => _.split(str, sep));
let map = _.curry((fn, arr) => _.map(arr,fn));
let join = _.curry((sep, arr) => _.join(arr, sep));

// debug 函数
let trace = _.curry((flag, data) => {
    console.log(flag,data)
    return data;
});

let compose = _.flowRight(trace("join") ,join("-"),trace("map") ,map(_.lowerCase) ,trace("split") ,split(" "));
console.log(compose(str));
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值