Js中的函数柯里化

2020-03-08

高阶函数:参数是函数或返回值是函数
比如 forEach, map, filter, sort, reduce, 函数柯里化

函数柯里化 Currying


是高阶函数的一种,将多参数函数转换为单一参数函数。
用于将复杂功能拆分成更小的逻辑单元,使其更容易理解、使用和测试。
缺陷:大量嵌套作用域和闭包函数会带来内存和速度花销
核心思想:fn(a,b,c) => fn(a)(b)(c)

1
2
3
4
5
6
7
8
9
10
11
function add(x, y) {
return x+y
}
// 柯里化后
function add2(x) {
return function (y) {
return x+y
}
}
add(1,2) // 3
add2(1)(2) // 3

1. 参数复用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 封装一个正则判断
function check(reg, txt) {
return reg.test(txt)
}
check(/\d+/g, 'test');

// 柯里化后
function check2(reg) {
return function(txt) {
return reg.test(txt)
}
}
var hasNumber = check2(/\d+/g);
var hasLetter = check2(/[a-z]+/g);
hasNumber('test1');
hasLetter('21212');

2. 陆续传参

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function add(){
var args = [...arguments];
var fn = function(){ // 接收陆续传参,利用闭包,将参数全部添加至args
args.push(...arguments);
return fn
};
fn.toString = function(){
return args.reduce((a,b)=>{
return a+b; // 计算args数组元素之和
});
};
return fn
}
add(1)(2)(3) // 6
add(1,2)(3) // 6
add(1)(2)(3)(4) // 10

3. 延迟执行

1
2
3
4
5
6
7
8
9
10
11
// bind()的实现机制就是柯里化
Function.prototype.bind = function (context) {
var _this = this;
var args = [...arguments]; // arguments是类数组对象,不能直接赋值
return function() {
return _this.apply(context, args)
}
}

f = func.bind(obj);
f(args);



反柯里化 UnCurrying


把已经内置的特定条件从函数中解放出来,作为参数,从而提高函数的适用范围。
应用:call/apply,把函数的调用对象当做参数传给函数
核心思想:fn(a)(b)(c) => fn(a,b,c)