柯里化 多参 (多元函数) ---> 单参 (一元函数)

柯里化的经典例子 :    add(1,2,3,4,5)  ---->  finalAdd(1)(2)(3)(4)(5)

原函数 

function add(num1, num2, num3, num4, num5) {
   return num1 + num2 + num3 + num4 + num5
}

实现思路:

finalAdd(1)   返回的是一个函数..............finalAdd(1)(2)   返回的仍然是一个函数...............

可以得出finalAdd的大致框架:

function finalAdd() {
   return function t() {}
}

我们可以很暴力的写出以下代码

function add(num1) {
    return function(num2) {
        return function(num3) {
            return function(num4) {
                return function(num5) {
                    return num1 + num2 + num3 + num4 + num5;
                };
            };
        };
    };
}

可以看到 finalAdd(1)(2)(3)(4)(5)就是不断递归返回的函数 ,递归结束的条件可以根据形参的个数来判断,对上述代码进行优化

function finalAdd(fn){
    const len =  fn.length // 传入fn的参数个数,根据这个个数来判断什么时候结束递归
    return function t(){
        const innerLength = arguments.length //传入实参的个数
        const args = Array.prototype.slice.call(arguments) // 类数组---> 真实数组
        if(innerLength >= len) {
            return fn.apply(undefined,args)
        }else{
            const innerArgs = Array.prototype.slice.call(arguments) // 类数组---> 真实数组
            const concatargs = args.concat(innerArgs)
            return t.apply(undefined,concatargs)
        }
    }
}

 这个函数finalAdd(1,2)(3)(4,5)也是可以的

如果不知道形参的个数呢,哪又该怎么办???

原始函数是这样的呢??

function add(...nums) {
     return nums.reduce((sum, num) => sum + num)
}

 这个时候就需要一个数据来记录累计传的参数,这里用数组来实现

function curryAdd(fn) {
    // 累积参数的数组
    let accumulatedArgs = []

    // 定义一个内部函数,用于累积参数和计算结果
    function curried(...args) {
    // 将传入的参数加入累积参数数组
    accumulatedArgs = [...accumulatedArgs, ...args]

    // 返回一个新的函数,继续累积参数或计算结果
    return function (...newArgs) {
         if (newArgs.length === 0) {
            // 如果没有传入新的参数,则计算结果并返回
            const result = fn(...accumulatedArgs)
            accumulatedArgs = [] // 记得重置数组哦
            return result
          } else {
            // 否则继续累积参数
            return curried(...newArgs)
          }
        }
    }

     // 返回初始的 curried 函数
     return curried()
 }

const curriedAdd = curryAdd(add)

  // 调用示例
console.log(curriedAdd(1)(2)(3)(4)(5)()) // 输出 15
console.log(curriedAdd(10, 20)(30, 40)()) // 输出 100
console.log(curriedAdd(1)(2)(3)(4, 5)()) // 输出 15

  • 18
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值