函数柯里化手写实践
什么是函数的柯里化:柯里化(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的保存值提供下一个需要执行的函数。