作者:就就解决 | 来源:互联网 | 2024-12-05 17:13
在研究函数柯里化的过程中,参考了一篇GitHub上的文章 链接,其中作者提供了一种实现柯里化的思路:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| function curry(fn, length) {
length = length || fn.length; // 默认参数数量
return function (...args) {
if (args.length >= length) { // 参数足够时直接调用原函数
return fn.apply(this, args);
} else {
return curry(fn.bind(this, ...args), length - args.length); // 继续收集参数
}
}
} |
该实现中,通过检查已收集的参数数量是否达到预期,决定是立即执行函数还是继续收集参数。测试示例如下:
1 2 3 4 5 6 7 8 9 10 11 12 13
| const add = curry(function(x, y, z) {
return x + y + z;
});
console.log(add(1)(2)(3)); // 输出: 6 console.log(add(1, 2)(3)); // 输出: 6 console.log(add(1, 2, 3)); // 输出: 6 console.log(add(1)(2, 3)); // 输出: 6 |
然而,有读者指出,实际上在递归调用curry
时并不需要显式传递length - args.length
,因为fn.bind(this, ...args)
返回的新函数的length
属性已经自动反映了剩余需要的参数数量。简化后的代码如下:
1 2 3 4 5 6 7
| function curry(fn) {
return function (...args) {
return args.length >= fn.length ? fn.apply(this, args) : curry(fn.bind(this, ...args));
};
} |
这是因为Function.prototype.bind
方法创建的新函数,其length
属性会根据绑定的参数数量自动减少。具体来说,如果原始函数需要三个参数,而我们绑定了两个参数,则新函数的length
将为1,表示还需要一个参数才能调用函数。这一特性使得我们在递归过程中无需手动管理剩余参数的数量,简化了柯里化的实现。