函数柯里化,是计算机科学中的一种技术,是把接受多个参数的单一函数改写成接受不定参数的多个函数,并且返回的仍然是可接受不定数量参数的函数。
函数柯里化的主要作用在于将原来不可中断的函数执行变成了多个可中断的短函数执行。于是中间这个中断的过程我们就可以做很多操作,参数校验,提前返回,延迟执行,等等。其实有点类似js中的generate,其实我第一时间接触到柯里化这个概念,联想到的就是generate。
其实实现的主要原理在js中就是闭包和递归。利用闭包持有args和this变量,递归的将所有参数累计,而后执行原函数即可。而添加了executionNums就可以手动选择执行次数。并且可以利用valueOf手动中断执行,获取结果
实现:
function currying(fn, executionNums = 9999) {
return function() {
let args = Array.prototype.slice.call(arguments, 0)
let curTime = 1
const curryFn = function () {
Array.prototype.push.call(args, arguments)
if (curTime + 1 < executionNums) {
++curTime
return curryFn
}
curryFn.toString = curryFn.valueOf = function () {
//这里本来想清除一些变量避免内存泄漏,但其实这里面的变量被持有的源头是外面adder,
//当adder被销毁后,里面的变量也自然被销毁,如果手动在这里清除反而容易出现不能预料的bug
return fn.apply(this, args)
}
return curryFn.valueOf()
}
return curryFn
}
}
function add() {
return [].reduce.call(arguments, (a, b) => a + b )
}
const adder = currying(add, 3)
adder(1)(2, 3)(4) // 10