假如一个函数只能接受一个参数,那么这个函数怎么实现;因为高阶函数是可以当做参数传递和返回值的;所以问题就简化了:写一个只有一个参数的函数;而这个函数返回一个带参数的函数;这样就实现了能写连个参数的函数;这就是函数柯里化;
function add(a,d){
return a+d;
};
function curry(a){
return function(d){
return a+d;
}
};
var add2=curry(2);
console.log(add2(3));//5
改为通用版本;
const curry = (fn, ...arg) => {
let all = arg;
return (...rest) => {
all.push(...rest);
return fn.apply(null, all);
}
}
let add2 = curry(add, 2)
console.log(add2(8)); //10
add2 = curry(add);
console.log(add2(2,8)); //10
;
function add(a,b){
return a+b;
}
var curry = (fn, ...arg) => {
let all = arg || [],
length = fn.length;
return (...rest) => {
let _args = all.slice(0); //拷贝新的all,避免改动公有的all属性,导致多次调用_args.length出错
_args.push(...rest);
if (_args.length < length) {
return curry.call(this, fn, ..._args);
} else {
return fn.apply(this, _args);
}
}
}
var add2 = curry(add, 2);
console.log(add2())
console.log(add2(8)); //10
add2 = curry(add);
console.log(add2(2,8)); //10
这里代码逻辑其实很简单,就是判断参数是否已经达到预期的值(函数柯里化之前的参数个数),如果没有继续返回函数,达到了就执行函数然后返回值,唯一需要注意的点我在注释里写出来了all相当于闭包引用的变量是公用的,需要在每个返回的函数里拷贝一份;
var currying=(fn,...args)=>{
let all=args||[];
length=fn.length;
return (...rest)=>{
let _args=all;
_args.push(...rest);
if(rest.length===0){
return fn.call(this,args)
}else{
return currying.apply(this,fn,..._args)
}
}
};
var test2=currying(function(...rest){
let args=rest.map(val=>val*10);
console.log(args);
})
个人理解;柯里化最终用的还是闭包的一些思想;最终获取到最终的变量进行保存;然后在给到函数进行处理;这样就形成了闭包;