函数柯里化手写实践

156 阅读1分钟

函数柯里化手写实践

什么是函数的柯里化:柯里化(Currying)是将一个多参数函数转换为一系列单参数函数的过程。每次调用返回一个新的函数,直到收集所有参数后才执行原始函数。

情况一:不涉及柯里化对象函数属性,无需考虑this绑定:

var fn = function(a,b,c){
    return a+b+c;
}
​
//写法:使用展开运算符
 function curryIt(func){
     return function curried(...args){
         if(args.length===func.length){
             // return func.apply(this,args);
             return func(...args)
         }else{
             return function(...args2){
                 // return curried.apply(this,args.concat(args2));
                 let newArgs = args.concat(args2);
                 return curried(...newArgs);
             }
         }
     }
 }
​
let curFunc = curryIt(fn);
console.log(curFunc(1)(2)(3));//6

此时返回的函数调用,由于内部根本没有涉及this(涉及this大部分情况是从某个对象里取函数),所以这里的apply只是利用了参数数组输入执行的功能,可以由数组展开运算符代替,因此apply的第一个参数this无关紧要(事实上,顶层环境调用函数this默认为global(module.export)/window对象)

情况二:涉及柯里化对象函数属性,必须考虑this绑定:

var objTest = {
    val:5,
    calFunc: function(a,b,c){
        return this.val+a+b+c;
    }
}
//写法:使用apply和call绑定
function curryIt(func){
    let _this=this;
    return function curried(...args){
        if(args.length===func.length){
            return func.apply(_this,args);
        }else{
            return function(...args2){
                return curried.apply(_this,args.concat(args2));
            }
        }
    }
}
​
let curryFuncInObj = curryIt.call(objTest,objTest.calFunc);
console.log(curryFuncInObj(1)(2)(3));

在第一次柯里化函数的时候,就要保存当前的this(通过call执行curryIt函数),形成闭包,将这个this的保存值提供下一个需要执行的函数。