函数式编程--柯里化&函数组装

101 阅读2分钟

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

特点:

  • 输入与输出:函数组合的输入和输出都是函数。每个函数都接收一个或多个参数,并返回一个值
  • 函数组合中的函数按照一定的顺序连接起来,前一个函数的输出作为后一个函数的输入。
  • 数据流向:数据在函数组合中的流向是从左到右,每个函数对数据进行处理或转换,负责某个特定的功能