位置:首页 > 软件操作教程 > 编程开发 > JavaScript > 问题详情

JavaScript 函数合成

提问人:刘团圆发布时间:2020-11-25

■设计思路

在函数式编程中,经常见到如下表达式运算:

    a(b(c(x)));

这是“包菜式”多层函数调用,但不是很优雅。为了解决函数多层调用的嵌套问题,我们需要用到函数合成。函数合成的语法形式如下:

var f = compose (a, b, c);        //合成函数

f (x);

例如:

var compose = function (f, g) {        //两个函数合成

    return function (x) {

        return f(g (x));

    };

};

var add = function (x) { return x + 1;}       //加法运算

var mul = function (x) { return x * 5;}       //乘法运算

compose (mul, add) (2) ;         //合并加法运算和乘法运算,返回15

    在上面的代码中,compose函数的作用就是组合函数,将函数串联起来执行,将多个函数组合起来,一个函数的输出结果是另一个函数的输入参数,一旦第一个函数开始执行,就会像多米诺骨牌一样 推导执行了。


■实例设计

    下面来完善compose实现,实现无限函数合成。设计思路:既然函数像多米诺骨牌式的执行,可以使用递归或迭代,在函数体内不断地执行arguments中的函数,将上一个函数的执行结果作为下一个执行函数的输入参数。

【实现代码】

//函数合成,从右到左合成函数 

var compose = function () {

    var _arguments = arguments;           //缓存外层参数

    var length = _arguments. length;      //缓存长度

    var index = length;                   //定义游标变量

    //检测参数,如果存在非函数参数,则抛出异常 

    while (index--) {

       if (typeof —arguments[index] !== 'function') { 

           throw new TypeError (’ 参数必须为函数!');

       }

    }

    return function () {

        var index = length-1;    //定位到最后一个参数下标

        //如果存在2个及以上参数,则调用最后一个参数函数,并传入内层参数 

        //否则直接返回第1个参数函数

        var result = length ?_arguments[index].apply(this, arguments) : arguments[0];

        //迭代参数函数

        while ( index——){

            //把右侧函数的执行结果作为参数传给左侧参数函数,并调用 

            result = —arguments[index]•call(this, result);

        }

        return result; //返回最左侧参数函数的执行结果

    }

}

//反向函数合成,即从左到右合成函数 

var composeLeft = function () {

    return compose.apply(null, [].reverse.call ( arguments));

}

【应用代码】

    在上面的实现代码中,composeO函数是根据参数顺序,从右到左进行合成,当然也可以把参数函数按从左到右进行合成,实现代码参考composeLeft()函数;同时在compose体内添加了一层函数的校验,允许传递一个或多个参数。

var add = function (x) { return x + 5; } //加法运算

var mul = function (x) { return x * 5; } //乘法运算

var sub = function (x) { return x - 5; } //减法运算

var div = function (x) { return x / 5; } //除法运算

var fn = compose(add, mul, sub, div);

console.log (fn (50) ) ;                 //返回30

var fn = compose(add, compose(mul, sub, div));

console.log (fn (50) ) ;                 //返回30

var fn = compose(compose(add, mul), sub, div);

console.log (fn (50) ) ;                 //返回30

上面几种组合方式都可以返回30。注意,排列顺序要保持一致。

继续查找其他问题的答案?

相关视频回答
回复(0)
返回顶部