函数柯里化
理解: 指的是将一个接受多个参数的函数 变为 接受一个参数返回一个函数的固定形式,这样便于再次调用,例如f(1)(2)
例如 常见的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接收一个函数,并且返回一个函数用于处理剩下的参数,因此可以连续两次调用,即curr(add,10)(20) 返回30
难度升级
此时一个简单的柯里化完成,但是如果遇到f(1)(2)(3)...等连续调用多次的时候,则会显得无力,此时需要一个更加复杂的柯里化,递归柯里化
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
注意:call和apply的区别
- 两者都是改变函数的this指针,如果第一个参数为null或者undefined则默认指向 window
- 不同的是call接收的第二个参数是 所有的实参,而apply接收的是一个数组
- 例如 fn.call(obj,1,2,3) fn.apply(obj,[1,2,3])
练习
实现一个函数,使得其能完成如下功能
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 }
来源:https://www.cnblogs.com/ailingstar/p/12425649.html