概念
- 柯里化是指这样一个函数(假设叫做createCurry),他接收函数A作为参数,运行后能够返回一个新的函数。并且这个新的函数能够处理函数A的剩余参数。
简单场景下的柯里化
javascript
1 | function add(a, b, c) { |
通用函数柯里化的实现(createCurry):
思路
- 柯里化函数的运行过程其实是一个参数的收集过程,我们将每一次传入的参数收集起来,并在最里层里面处理。
- func有一个length属性,表示函数定义时所需参数个数;
- 通过函数的length属性判断合适停止收集参数,返回计算结果;
实现:
javascript1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20function createCurry(func, args) {
var argsLength = func.length;
var args = args || [];
return function() {
var _args = [].slice.apply(arguments);
[].push.apply(_args, args);
if (_args.length >= argsLength) {
return func.apply(null, _args);
}
return createCurry(func, _args);
}
}
function add(a, b, c) {
return a + b + c;
}
const _add = createCurry(add);
_add(1)(2)(3);
无限柯里化
- 问题:实现一个add方法,使计算结果能够满足如下预期javascript
1
2
3add(1)(2)(3) = 6;
add(1, 2, 3)(4) = 10;
add(1)(2)(3)(4)(5) = 15; - 思路:
- 函数的隐式转换:当我们直接将函数参与其他的计算时,函数会默认调用valueOf/toString方法,直接将函数体转换为字符串参与计算;
- 当我们同时重写函数的toString方法与valueOf方法时,最终的结果会取valueOf方法的返回结果;
- 实现:javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23function unlimitedAdd() {
var args = [].slice.call(arguments);
var adder = function() {
var _adder = function() {
args.push(...arguments);
return _adder;
}
_adder.toString = function() {
return args.reduce(function(a, b) {
return a + b;
})
}
return _adder;
}
return adder(...args);
}
console.log(unlimitedAdd(1)); // f 1
console.log(unlimitedAdd(1)(2)); // f 3
console.log(unlimitedAdd(1)(2)(3)); // f 6