js中的函数柯里化

柯里化(Currying)

在计算机科学中,柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数的函数,并且返回接受余下的参数且返回结果的新函数的技术。(返回和原函数相同的结果)

来个例子
假如我们封装了一个柯里化函数,那么我们能干什么呢?

function Curry(fn){}

我现在有一个求和函数,如下

function add(a, b, c, d) {
  return a+b+c+d;
}

这个柯里化函数能做到什么呢?

// 封装一个柯里化函数  期待每一次将剩余参数进行传递
var newAdd = Curry(add);

newAdd(1)(2,3)(4);
newAdd(1)(2)(3)(4);
newAdd(1,2)(3,4);
newAdd(1,2,3,4);

每一次我都可以传进任意参数,可以传进全部,也可以只传一个,直到我获得到了所有的参数为止,并且所得到结果和我正常调用的 add(1,2,3,4) 一样。

实现柯里化,我们怎么才能让这个函数在接受一个函数可以继续传参呢,在上一个函数运行结束后,返回一个函数。
众所周知,函数名后面带个括号是执行这个函数

newAdd(1

我们传入第一个参数时去判断,本次传入的实参的个数,和原来函数形参的个数是否一样?怎么判断呢?
函数的length属性可以获取,形参个数。
获取实参个数的话,就用arguments.length 因为arguments是个实参有映射关系的

如果传入实参个数不够那么就要返回一个函数,获取新的实参

所以最后的函数如下,我会把每一段重要的都注释,很简单。

 function Curry(fn) {
            // 通过length属性去获取函数形参的个数
            var lon = fn.length;
            // 用于计算你实参的个数
            var num = 0;
            //创建一个数组,用来保存每次实参的值
            var arr = [];
            //返回一个函数,因为是闭包所以上面的值都不会出现重置的情况,不需要形参
            //(因为你不知道他会传入几个实参),通过arguments获取
            return function kl() {
            //遍历,把每次传入的实参,放入数组中
                for (var i = 0; i < arguments.length; i++) {
                    arr[num] = arguments[i];
                    num++;
                }
                //只要现在已有的实参个数不等于原函数形参个数,就返回这个函数,继续去获取实参
                if (num<lon) {
                    return kl;
                } else {
                //否则的话就把num清零方便下一个调用
                    num=0;
                    //当实参数和形参数相等时执行函数,使用的apply,因为所有的实参都存在数组里
                   return fn.apply(this,arr);
                }
            }
        }

上面就是我思考的柯里化函数,那来验证一下吧

// 四个参数
        var newAdd = Curry(add);
        function add(a, b, c, d) {
            return a+b+c+d;
        }
        console.log(newAdd(1)(3)(2)(4));
        console.log(newAdd(1,2)(3,4));
        console.log(newAdd(1)(2,3)(4));

        // 六个参数
        var newBdd = Curry(bdd);
        function bdd(a, b, c, d, e, f) {
           return a+b+c+d+e+f;
        }
        console.log(newBdd(1,2)(3,4)(5)(6));
        console.log(newBdd(1,2,3,4,5,6));

在这里插入图片描述
成功的达到了想要的效果。

(如果这篇文章有什么问题请及时联系我!)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值