首先先看一个简单的函数
function sum(a,b,c){
return a+b+c;
}
很简单吧,这是一个三数的相加操作,然后我想能不能这样操作也能执行成功三位相加的操作,例如这样传值sum(1)(2)(3),这该怎么做?这其实也是一个比较经典的面试题,答案如下:
function sum(x){
return function(y){
return x+y;
}
}
这样就是一个函数的柯里化,思想就是将原本需要三个参数才能运行的函数,转化为,可以先让一个函数去接受一个参数,调用后,再返回去调用剩余其他的参数,直到完成所有参数的调用
网上有很多实现柯里化的方式,以下是我感觉最容易的理解的写法
function curry(fn,currArgs){ // 这里的fn就是sum方法
return function() {
let args=[].slice.call(arguments);
// 首次调用时未提供参数currArgs,因此不用进行拼接执行
if(currArgs!==undefined){
args=args.concat(currArgs); // 这里的currArgs是上次递归传递进来的,也就是上次递归的args
}
// 递归调用
if(args.length<fn.length){
return curry(fn,args);
}
return fn.apply(null,args); // 这里调用了apply方法,将收集起来的args参数全都传入fn中
}
}
那现在我们该怎么用呢?比如现在我又有一个需求,那就是不止要可以算出sum(1)(2)(3)的值还要算sum(1)(1,2)甚至sum(1,2,3)的值,那我们怎么做?
简直直接把sum函数用我们刚才写好的curry函数包裹起来既可以
function sum(a,b,c){
return a+b+c;
}
const fn=curry(sum);
fn(1)(2)(3); // 6
fn(1)(2,3); // 6
fn(1,2,3); //6