1. 什么是函数柯里化
柯里化(Currying)又称部分求值,一个柯里化的函数首先会接收一些参数,接收了这些参数后,该函数并不会立即求值,而是继续返回另外一个函数,刚才传入的参数在函数形成的闭包中被保存起来。待到函数被真正需要求值的时候,之前传入的所有参数都会被一次性用于求值。
柯里化是一种函数的转换,它是指将一个函数从可调用的 f(a, b, c) 转换为可调用的 f(a)(b)(c)或者f(a, b)(c)或者f(a)(b, c)
柯里化不会调用函数。它只是对函数进行转换。
2. 函数柯里化实现
function curry(fn,...args){
return fn.length <= args.length ? fn(...args) : curry.bind(null,fn....args);
}
function curry(func) {
return function curried(...args) {
if (args.length >= func.length) {
return func.apply(this, args);
} else {
return function(...args2) {
return curried.apply(this, args.concat(args2));
}
}
};
}
// 测试
function add (num1, num2, num3, num4, num5) {
return num1 + num2 + num3 + num4 + num5;
}
const finalFun = curry(add);
const result1 = finalFun(1)(2)(3)(4)(5);
const result2 = finalFun(1, 2)(3)(4)(5);
const result3 = finalFun(1,2,3)(4)(5);
const result4 = finalFun(1,2,3)(4, 5);
console.log(result1, result2, result3, result4); // 15 15 15 15
3. 函数柯里化应用
- 参数复用:即如果函数有重复使用到的参数,可以利用柯里化,将复用的参数存储起来,不需要每次都传相同的参数
- 延迟执行:传入参数个数没有满足原函数入参个数,都不会立即返回结果,而是返回一个函数。(bind方法就是柯里化的一个示例)
- 函数式编程中,作为compose, functor, monad 等实现的基础
4. 函数柯里化的优缺点
4.1. 优点
- 柯里化之后,我们没有丢失任何参数:log 依然可以被正常调用。
- 我们可以轻松地生成偏函数,例如用于生成今天的日志的偏函数。
- 入口单一。
- 易于测试和复用。
4.2. 缺点
- 函数嵌套多
- 占内存,有可能导致内存泄漏(因为本质是配合闭包实现的)
- 效率差(因为使用递归)
- 变量存取慢,访问性很差(因为使用了arguments)