写一个compose函数
# 写一个compose函数
组合多个函数,从右到左,比如:compose(f, g, h)
最终得到这个结果 (...args) => f(g(h(...args)))
.
实现
function compose(...funcs) {
if (funcs.length === 1) {
return funcs[0]
}
return funcs.reduce((a, b) => (...args) => a(b(...args)))
}
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
compose创建了一个从右向左执行的数据流。如果要实现从左到右的数据流,可以直接更改compose的部分代码即可实现
- 更换Api接口:把
reduce
改为reduceRight
- 交互包裹位置:把
a(b(...args))
改为b(a(...args))
compose 函数演化
传入一个数值,计算数值乘以10再加上10,再减去2
实现起来很简单。
const calc = (num) => num * 10 + 10 - 2;
calc(10); // 108
1
2
2
但这样写有个问题,不好扩展,比如我想乘以10时就打印出结果。 为了便于扩展,我们分开写成三个函数。
const multiply = (x) => {
const result = x * 10;
console.log(result);
return result;
};
const add = (y) => y + 10;
const minus = (z) => z - 2;
// 计算结果
console.log(minus(add(multiply(10))));
// 100
// 108
// 这样我们就把三个函数计算结果出来了。
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
再来实现一个相对通用的函数,计算这三个函数的结果
const compose = (f, g, h) => {
return function(x){
return f(g(h(x)));
}
}
const calc = compose(minus, add, multiply);
console.log(calc(10));
// 100
// 108
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
这样还是有问题,只支持三个函数。我想支持多个函数。 我们了解到数组的reduce方法就能实现这样的功能。 前一个函数
const compose = (...funcs) => {
return funcs.reduce((a, b) => {
return function(x){
return a(b(x));
}
})
}
const calc = compose(minus, add, multiply);
console.log(calc(10));
// 100
// 108
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11