一、函数柯里化是什么?
百度百科中对函数柯里化的解释是:在计算机科学中,柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且返回结果的新函数的技术。
举个🌰说明一下:
比如我们需要求三个数的和,我们一般的做法就是一次性传入三个参数进行求和:
function add(a, b, c){
return a + b + c
}
//我们一般调用函数的方式
add(1, 2, 3)
而函数柯里化就是每次传入单一的参数,如下所示:
add(1)(2)(3)
那么,此时add函数应该如何写呢?
二、如何实现函数柯里化?
1、第一种方法:多层return嵌套
我们使用add(1)(2)(3)的方式调用函数,就需要每次都返回一个函数,add(1)(2)(3)就相当于:
var fn1 = add(1)
var fn2 = fn1(2)
fn2(3)
因此add函数可以这样写:
<script>
function add(a){
return function(b) {
return function(c) {
return a + b + c
}
}
}
console.log(add(1)(2)(3)); //6
</script>
这里使用到了闭包的原理来实现add函数,这种方法比较简单,很容易就能想到,但是这种方法并不通用,所以我们可以封装一个函数,用于将普通函数转成柯里化函数。
2、第二种方法:将普通函数转成柯里化函数
柯里化函数执行的过程就是一个收集参数的过程,因此我们只要收集完所有参数,然后把参数传递给普通函数执行即可。
<script>
function add(a, b, c) {
return a + b + c
}
function curry(fun, args) {
//获取fun函数的形参个数
var len = fun.length
var args = args || []
return function () {
//arguments是实参列表,是一个类数组对象,使用slice方法可以将它转成数组
//收集本次的参数
var arrArgs = Array.prototype.slice.call(arguments)
//拼接前面收集到的参数
arrArgs = arrArgs.concat(args)
//如果实参个数小于形参个数,说明参数还没有收集完,使用递归继续收集
if (arrArgs.length < len) {
return curry.call(this, fun, arrArgs)
}
//收集完了,则执行fun函数
//1.使用apply
return fun.apply(this, arrArgs)
//2.使用call
// return fun.call(this, ...arrArgs)
//3.使用bind
// return fun.bind(null, ...arrArgs)()
}
}
//将add函数转成柯里化函数
var addCurry = curry(add)
//每次可以传递任意个参数
console.log(addCurry(1)(2)(3)); //6
console.log(addCurry(1, 2)(3)); //6
console.log(addCurry(1)(2, 3)); //6
console.log(addCurry(1, 2, 3)); //6
</script>
版权归原作者 叶子yes 所有, 如有侵权,请联系我们删除。