先来看一个列子:
需求: 计算一个数先加上10再乘以10的值。
初始版本:
let calculation = x => (x + 10) * 10;
console.log(calculation(10)); // 200
命令式编程,不具备复用性
优化第一版:
let add = x => x + 10;
let multiply = y => y * 10;
let calculation = x => multiply(add(x));
console.log(calculation(10)); // 200
函数式编程,将程序分解成更可重用、更易于理解的函数,再将函数组合起来形成一个更易于推理的整体
优化第二版:
let add = x => x + 10;
let multiply = y => y * 10;
let compose = (f, g) => {
return function(x) {
return f(g(x));
};
};
let calculation = compose(multiply, add);
console.log(calculation(10)); // 200
根据组合函数的定义,我们需要将两个函数组合为一个函数
特点1: 两个函数都有一个参数;
特点2: 函数的执行顺序是从右到左;
特点3: 前面函数的执行结果是下一函数的参数
优化第三版:
let add = x => x + 10;
let multiply = y => y * 10;
let compose = (...args) => {
return function(x) {
return args.reduceRight(function(res, fun) {
return fun(res);
}, x);
};
};
let calculation = compose(multiply, add);
console.log(calculation(10)); // 200
通用
compose函数, 符合上面3点特性的同时,不限制组合的函数的个数
优化第四版:
let add = x => x + 10;
let multiply = y => y * 10;
let compose = (...args) => x => args.reduceRight((res, fun) => fun(res), x);
let calculation = compose(multiply, add);
console.log(calculation(10)); // 200
es6写法, 简化代码
总结
compose函数可以将需要嵌套执行的函数平铺,让我们专注于转换而不是数据
嵌套执行指的是 一个函数的返回值将作为另一个函数的参数