Function currying
Appreciated: refers to a function that accepts a plurality of parameter becomes a parameter returns function accepts a fixed form, it is easy to call again, for example, f (1) (2)
Common functions such as add
function add(a,b){
return a+b
}
// 变为
function curry(fn){
var firstArgs=Array.prototype.slice.call(arguments,1) //这里,arguments的第一个参数是fn,所以从1开始
var _cur=function(){
var nextArgs=[...arguments]
var allArgs=firstArgs.concat(nextArgs)
return fn.apply(this,allArgs)
}
return _cur
}
var add1=curry(add,10)
add1(10) //20
add1(20) //30
Curry current currying a receiving function, a function for processing and return the remaining parameters so that the two successive calls, i.e. curr (add, 10) (20) returns 30
Upgrade of difficulty
At this point a simple curried complete, but if you encounter f (1) (2) (3) ... and so many times when successive calls will seem weak, at this time requires a more complex currying recursive currying
function add(){
return [].reduce.call(arguments,(a,b)=>{
return a+b
},0)
}
function curry(fn){
var len=fn.length // fn.length 指的是函数需要接受的参数长度
var args=Array.prototype.slice.call(arguments,1)
var _adder= function(){
var _args=Array.prototype.slice.call(arguments) // 等价于arguments.slice()
if(_args.length==0){
return fn.apply(this,args)
}else{
[].push.call(args,..._args)
return _adder
}
}
_adder.toString=function(){
return _adder()
}
return _adder
}
var add1=curry(add)
console.log(add1(2)(2).toString()) //4
The difference between call and apply: Note
- Both are changing this function pointer, if the first parameter is null or undefined points to the default window
- Different call is received by the second parameter is all the arguments, and apply received is an array
- E.g. fn.call (obj, 1,2,3) fn.apply (obj, [1,2,3])
Exercise
Achieve a function, so that it can implement the following functions
add(1) //1
add(1)(2) //3
add(1)(1,2,3) //7
function add(){
var args=[...arguments]
var _adder= function(){
var _args=Array.prototype.slice.call(arguments)
if(_args.length==0){
return args.reduce((a,b)=>{
return a+b
},0)
}else{
[].push.call(args,..._args)
return _adder
}
}
_adder.toString=function(){
return _adder()
}
return _adder
}