手写柯里化函数
# 手写柯里化函数
在数学和计算机科学中,柯里化是一种将使用多个参数的一个函数转换成一系列使用一个参数的函数的技术。
function add(a, b) {
return a + b;
}
// 执行 add 函数,一次传入两个参数即可
add(1, 2) // 3
// 假设有一个 curry 函数可以做到柯里化
var addCurry = curry(add);
addCurry(1)(2) // 3
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
const multiArgFunction = (a, b, c) => a + b + c;
console.log(multiArgFunction(1, 2, 3)); // 6
const curryUnaryFunction = (a) => (b) => (c) => a + b + c;
curryUnaryFunction(1); // returns a function: b => c => 1 + b + c
curryUnaryFunction(1)(2); // returns a function: c => 3 + c
curryUnaryFunction(1)(2)(3); // returns the number 6
1
2
3
4
5
6
7
2
3
4
5
6
7
/**
* 柯里化:用闭包把参数保存起来,当参数的数量足够执行函数了,就开始执行函数
*/
var curry = (fn) =>
(judge = (...args) =>
args.length === fn.length ? fn(...args) : (arg) => judge(...args, arg));
// es6
const curry = (fn, ...args) =>
fn.length <= args.length ? fn(...args) : curry.bind(null, fn, ...args)
function curry(fn, ...args) {
// fn原函数
// ...args可以传入初始参数
// 返回一个函数
return function() {
// 缓存目前接收到的参数
let _args = [...args, ...arguments];
// 原函数应该接收的参数个数
let { len } = fn;
// 比较目前的参数累计与原函数应该接收的参数
if(_args.length < len) {
// 代表需要继续返回一个新函数
// 使用递归,形成闭包,保证函数独立,不受影响
return curry(fn, ..._args);
} else {
// 参数累计够了,执行原函数返回结果
return fn.apply(this, _args)
}
}
}
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
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