compose函数及其实现

compose 是函数式编程中一个非常重要的函数,compose的函数作用就是组合函数,将多个函数串联起来,上一个函数的输出作为下一个函数的输入。

效果如下:

function f1(x){
    return x+10;
}
function f2(x){
    return x*10;
}
function f3(x){
    return x-10;
}

let cal = compose(f1,f2,f3);
console.log(cal(5)));// compose的累加顺序是从右往左,结果为:((5-10)*10)+10 = -40 

那么如何实现呢?

最直接的想法:

let cal = f1(f2(f3(5)));
console.log(cal);//-40

或者说,我们再优化一下,将函数作为参数传进来,并返回一个匿名函数:

let compose1 = function(f1,f2,f3){
    return function(x){
        return f1(f2(f3(x)));
    }
}
let cal1 = compose1(f1,f2,f3);
console.log(cal1(5));//-40

但是核心问题没有解决,如何将 return f1(f2(f3(x))) 进行 “扁平化” ?

为了解决此问题,我们先熟悉js的reduce函数:

reduce() 方法接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值。

reduceRight() 方法的功能和 reduce() 功能是一样的,不同的是 reduceRight() 从数组的末尾向前将数组中的数组项做累加。

因为compose函数的定义是从末尾累加,所以我们选用reduceRight方法:

array.reduce(function(total, currentValue, currentIndex, arr), initialValue)

参数

描述

function(total,currentValue, index,

arr)

必需。用于执行每个数组元素的函数。

函数参数:

initialValue

可选。传递给函数的初始值

参数

描述

total

必需。初始值, 或者计算结束后的返回值。

currentValue

必需。当前元素

currentIndex

可选。当前元素的索引

arr

可选。当前元素所属的数组对象。

reduceRight的例子:

var nums = [2,3,5,4];
function getSum(total,x){
    //LOOP1:total+x = 14
    //LOOP2:total+x = 19
    //LOOP3:total+x = 22
    //LOOP4:total+x = 24
    return total+x;
}
console.log(nums.reduceRight(getSum,10));//24

下面,我们利用reduceRight将compose1进行改进:

let compose2 = function(){
    let args = [].slice.call(arguments);
    //[ [Function: f1], [Function: f2], [Function: f3] ]
    return function(x){
        //x=5
        return args.reduceRight(function(res,cb){
            //LOOP1:cb = [Function: f3]  res = 5
            //LOOP2:cb = [Function: f2]  res = -5
            //LOOP3:cb = [Function: f1]  res = -50
            return cb(res);
            //LOOP1:cb(res) = -5;
            //LOOP2:cb(res) = -50;
            //LOOP3:cb(res) = -40;
        } , x)
        //return -40
    }
}
let cal2 = compose2(f1,f2,f3);
console.log(cal2(5));//-40

对应的ES6写法:

const compose3= (...args) => x =>args.reduceRight((res,cb) => cb(res),x);
let cal3 = compose3(f1,f2,f3);
console.log(cal3(5));//-40
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值