我们的目标是给定一个初始值以后,用pipeline的方法实现不同函数运算的顺序执行,从而得出最终结果。
最终实现应该如下:
var result = pipeline(initialValue, func1, func2, func3...);
首先先写几个函数吧:
var double = n => n * 2;
var pow = n => n * n;
var pow3 = n => n * n * n;
这里用了ES6中的箭头函数。对于有返回值的函数,用箭头函数写出来简洁而清晰。
函数的顺序执行,就想到了前后的函数必须有联系。
我们可以用Array. reduce( ) 方法。
详细描述请见以下链接:
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce
函数式编程的一个基本思想就是,你可以把有返回值的函数当成一个变量在函数中传参调用。
所以我们可以这么写:
funcs.reduce(function(pre,cur){
return cur(pre);
}, val);
这里初始值为val, 也就是我们要传入pipeline计算的那个值。
在首次计算中, pre就是 val, 以后的pre值都是前次的return cur(pre);
稍稍动下脑筋,就知道此功能可以实现当前函数调用前次函数的返回值,从而实现流水线调用。
funcs是一个函数数组,第一我们想到的是用Array.push()。
实际上完全不用这么麻烦,可以用 … 运算符实现参数列表到数组的转换,这也是ES6的一个爽点。
貌似说得七七八八了,我们就来封装一下这个函数:
function pipeline(val, ...funcs) {
return funcs.reduce(function (pre, cur) {
return cur(pre);
}, val);
}
好,接下来我们直接传参:
var result = pipeline(2, double, pow, pow3); // 4096
完美执行!
可是这就完了吗?
不!这还没有get到函数式变成的精髓。
我们是有追求的屌丝码农。
极简!极简!极简!
那好,咱们就来装个内什么吧。。。
改写下:
var pipeline = (val, ...funcs) => funcs.reduce((pre, cur) => cur(pre), val);
一行代码搞定!
结果一样!
var result = pipeline(2, double, pow, pow3); // 4096
而且所传函数个数不限。
当然,代码的易读性很重要。
所以不装也罢。