函数柯里化
Chao 工程师

实现add(1)(2)(3) ==6 && add(1, 2, 3) == 6

利用 toString() valueOf()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function add() {
let args = Array.prototype.slice.call(arguments);

let adder = function() {
args.push(...arguments)
return adder;
}

adder.toString = function() {
return args.reduce((a, b) => {
return a + b
}, 0)
}

return adder;
}
console.log(add(1)(2)(3) == 6);
console.log(add(1, 2, 3) == 6);

实现add(1)(2)(3)() == add(1, 2)(3)() == add(1, 2, 3)() == 6

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function add() {
let args = Array.prototype.slice.call(arguments);

const adder = function () {
if (arguments.length === 0) { // 最后一次调用,直接计算结果
return args.reduce(function (a, b) {
return a + b;
}, 0);
} else { // 不是最后一次调用,将参数都保存下来
[].push.apply(args, arguments);
return adder;
}
}

return adder;
}

console.log(add(1, 2, 3)()) // 6
console.log(add(1, 2)(3)()) // 6
console.log(add(1)(2)(3)()) // 6

函数柯里化

使用柯里化对上面代码进行改进。

最终代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
function currying(fn) {
let args = [];

const adder = function () {
if (arguments.length === 0) { // 最后一次调用,直接计算结果
return fn.apply(this, args)
} else { // 不是最后一次调用,将参数都保存下来
[].push.apply(args, arguments);
return adder;
}
}

return adder;
}


// 使用柯里化函数求和
function add() {
let args = Array.prototype.slice.call(arguments);
return args.reduce(function (a, b) {
return a + b;
}, 0);
}
const sum = currying(add);
console.log(sum(1, 2, 3)()) // 6
console.log(sum(1, 2)(3)()) // 6 覆盖上一个
console.log(sum(1)(2)(3)()) // 6 覆盖前两个


// 使用柯里化函数排序
function sort() {
let args = Array.prototype.slice.call(arguments);
args.sort((a, b) => a - b);
return args;
}

const sortNumber = currying(sort);
console.log(sortNumber(3, 2, - 1, 0, 5, 4)())

如果想让每次执行 add() 都能返回结果。则进行如下改进:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
function add() {
let args = Array.prototype.slice.call(arguments);
return args.reduce(function (a, b) {
return a + b;
}, 0);
}

function currying(fn) {
let args = [];

const adder = function () {
[].push.apply(args, arguments);
return fn.apply(this, args)
}

return adder;
}

add = currying(add);

console.log(add(1)) // 1
console.log(add(2)) // 3
console.log(add(3)) // 6
console.log(add()) // 6
 Comments