1、柯里化
- 理解:把一个多参数函数转变为单参数的方法
案例:实现可拆分传参的累加函数 add(1, 2, 3) => f(1)(2)(3)
/**
* 思路:
* 1.处理最外层参数并处理
* 2.构造科里化结构 => 输出函数
* 3.传入参数无限拓展 => 递归 => 返回递归函数本身
* 4.参数执行累加,
* 5.toString()隐式转换该声明函数后返回
*/
const newAdd = function () {
// 第一次执行时,定义一个数组专门用来存储所有的参数
// var _args = Array.prototype.slice.call(arguments);
var _args = [...arguments];
// 柯里化结构-在内部声明一个函数,利用闭包的特性保存_args并收集所有的参数值
var _adder = function () {
_args.push(...arguments);
return _adder;
};
// 利用toString隐式转换的特性,当最后执行时隐式转换,并计算最终的值返回
_adder.toString() = function () {
return args.reduce((prev, cur) => prev + cur, 0);
}
return _adder;
}
console.log(newAdd(1)(2)(3).toString()); //6
console.log(newAdd(1, 2, 3)(4)==10); //true
console.log(newAdd(1)(2)(3)(4)(5)==15); //true
2、函数组装
- 理解:将多个函数按照一定的顺序连接起来,形成一个新的函数。这个新函数能够依次调用组合中的各个函 数,将每个函数的输出作为下一个函数的输入,最终产生最终的结果
- 水源 => 组合(水管 + 走线)=> 花洒
案例:对数组每一项乘指定数字后累加(使用reduce实现)
// 定义一个函数,用于将数组中的每个元素乘以指定的数字
const multiplyArr = num => {
return arr => arr.map(element => element * 2);
}
// 定义一个函数,用于将数组中的所有数字相加
const addNumFn = arr => {
const isInvalid = arr.some(item => isNaN(item))
if (isInvalid) {
return "只能传入数字"
}
return arr.reduce((prev, cur) => prev + cur, 0)
}
// 定义一个函数,用于组合多个函数,依次对输入值进行处理
const composeFn = (...inputFn) => {
if (inputFn.length === 1 && typeof inputFn[0] === 'function') {
return inputFn[0];
}
const isInvalid = inputFn.some((item,index) => typeof item !== 'function')
if (isInvalid) {
throw new Error('参数错误')
}
return function (initialNumArr) {
return inputFn.reduce((acc, cur) => cur(acc), initialNumArr)
}
}
// 使用示例
console.log(composeFn(multiplyArr(2), addNumFn)([1, 8, 6, 2, 4])); //42
console.log(composeFn(multiplyArr(2))([1, 8, 6, 2, 4])); //[2, 16, 12, 4, 8]
console.log(composeFn(addNumFn)([1, 8, 6, 2, 4])); //21
特点:
- 输入与输出:函数组合的输入和输出都是函数。每个函数都接收一个或多个参数,并返回一个值
- 函数组合中的函数按照一定的顺序连接起来,前一个函数的输出作为后一个函数的输入。
- 数据流向:数据在函数组合中的流向是从左到右,每个函数对数据进行处理或转换,负责某个特定的功能