JS 函数柯里化


函数柯里化

理解: 指的是将一个接受多个参数的函数 变为 接受一个参数返回一个函数的固定形式,这样便于再次调用,例如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
}


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM