概念
JavaScript中的函数柯里化是一种将接受多个参数的函数,转换为一系列接受单个参数的函数的技术。这种转换过程允许你部分应用函数的参数,并返回一个新的函数该函数等待接受余下的参数。
比如一个add函数,接受3个参数,计算3个参数的和然后返回值。函数柯里化之后呢,函数可以接受 <= 3个参数,然后返回函数可以继续接受参数,直到一共接受到3个参数,计算3个值的和返回
// 原函数
function add(a, b, c) {
return a + b + c;
}
// 调用
let result = add(1, 2, 3); //一下接受3个参数,计算然后返回值 6
// 柯里化函数
function curry(fn) {
// 实现方法
}
// 柯里化后
let curriedAdd = curry(add);
//调用看参数
let result2 = curriedAdd(1, 2)(3);
let result3 = curriedAdd(1, 2, 3, 4);
let result4 = curriedAdd(1)(2)(3);
代码实现
使用闭包方式实现思路:
- 判断原函数的参数个数用 fn.length实现,当前一共传入参数的个数可以用 args.length 实现。
- 当 args.length >= fn.length 时候,说明传进的参数个数比原函数参数多,直接调用原函数就行。
- 反之,就把当前传入的参数 合并起来,继续递归调用。
// 定义
function curry(fn) {
return function curried(...args) {
console.log('当前传入的参数个数 = ', args.length);
console.log('原函数参数的个数 = ', fn.length);
// 如果比原来数的参数多,就调用原函数就行
if(args.length >= fn.length) {
return fn.apply(this, args);
} else {
// 少的话,就继续递归调用 curried 函数,并把之前的参数都合并起来。
return function(...moreArgs) {
return curried.apply(this, args.concat(moreArgs));
}
}
}
}
// 使用
function add(a, b, c) {
return a + b + c;
}
const curriedAdd = curry(add);
const result = curriedAdd(1)(2)(3); // 等价于 add(1, 2, 3)
console.log(result); // 输出 6