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