解释:只传递给函数一部分参数来调用它,让它返回一个函数去处理剩下的参数。
首先实现add(1)(2)(3)
const add = function(x){
return function(y){
return function(z){
return x+y+z
}
}
}
console.log(add(1)(2)(3));
简化为箭头函数的形式
const add = x => y => z => x + y + z;
console.log(add(1)(2)(3));
此时函数的形参只能是一个,为了实现下面的结构,得重新写
add(1)(2)
add(1)(2)(3)
add(1, 2)(3);
add(1)(2, 3);
如果仅仅实现两个括号add(1)(2),可以通过内部return 一个函数来接收第二个括号的函数参数。
function sum(){
var args = Array.prototype.slice.call(arguments)
//1.伪数组转化为数组
let inner = function(){
args.push(...arguments)
//3.将return出去的inner接收的参数放入到args中,此处用到了闭包。
let total = args.reduce((prev,item) => prev+item)
return total
}
return inner
//2.将inner返回出去接收其余参数
}
console.log(sum(6)(2))
此处,仅仅只能接收两次函数参数,如果为了接收更多参数就需要在inner内再返回一个函数,对于更复杂的场景,明显不适用。
通过在inner里面继续return inner来实现函数参数的收集但是由于函数内部已经return了,所以无法再对args进行处理并return出来
function sum(){
var args = Array.prototype.slice.call(arguments)
let inner = function(){
args.push(...arguments)
console.log(args)
return inner
}
return inner
}
通过改写toString方法来实现
function sum(){
var args = Array.prototype.slice.call(arguments)
let inner = function(){
args.push(...arguments)
return inner
}
inner.toString = function(){
return args.reduce((prev,curr) => prev+curr)
}
return inner
}
以上是实现了sum方法,此时传入的参数可以不限定
若限定传入的参数为3
比如:sum(1)(2)(3)
可以封装一个curry函数来实现
var sum = function(a,b,c){
return a+b+c
}
console.log(sum.length)
function curry(fn, currargs){
return function (){
let args = Array.prototype.slice.call(arguments)
if(currargs != undefined){
args = args.concat(currargs)
}
//递归调用
if(args.length < fn.length){
return curry(fn,args)
}
//fn.length返回的是fn参数的个数
if(args.length == fn.length){
return fn.apply(null,args)
}else{
return "error"
}
}
}
var fn = curry(sum)
console.log(fn(1)(2)(3))//6