偏函数与函数柯里化
一、偏函数
所谓偏函数,就是固定一个函数的一个或者多个参数,返回一个新的函数,这个函数用于接受剩余的参数。
1. 工厂方法
首先来看一个简单的例子:
function add(a, b) {
return a + b;
}
add(1, 2);
add(1, 3);
add(1, 4);
add(1, 5);
add(1, 6);
我们发现,调用 add 方法时,第一个参数相同,但是我们写了 5 遍,鉴于此种情况,我们可以将 add 方法封装成偏函数的形式来实现更加简洁的代码。
// 入参函数
function add(a, b) {
return a + b;
}
// 生产偏函数的工厂
function partial(fn, a) {
return function (b) {
return fn(a, b);
};
}
// 得到偏函数
var parAdd = partial(add, 1);
parAdd(2);
parAdd(3);
parAdd(4);
parAdd(5);
parAdd(6);
由上边我们可以看到,偏函数也利用了闭包的原理。
2. bind 方法
由于 bind 函数会返回一个未执行的新函数,且新函数与被调函数具有相同的函数体,所以我们也可以使用 bind 方法来实现偏函数
function add(a, b) {
return a + b;
}
var parAdd = add.bind(null, 1);
parAdd(2);
parAdd(3);
parAdd(4);
parAdd(5);
parAdd(6);
二、函数柯里化
柯里化是另一个有趣的处理函数技术。柯里化(Currying):转换一个调用函数 f(a,b,c)为 f(a)(b)(c)方式调用。下面实现了一个柯里化函数,执行一个两元参数函数,即转换 f(a,b)至 f(a)(b):
function add(a, b) {
return a + b;
}
function curry(fn) {
return function (a) {
return function (b) {
return fn(a, b);
};
};
}
var carriedSum = curry(add);
carriedSum(1)(2);
- curry(func)的结果是 function(a)的一个包装器。
- 当调用 sum(1)是,参数被保存在词法环境中,然后返回新的包装器 function(b)
- 然后 sum(1)(2)提供 2 并最终调用 function(b),然后传递调用给原始多参数函数 sum。
1. 无限加参
function add(...args) {
var result = 0;
if (args.length > 0) {
for (var i = 0; i < args.length; i++) {
result += args[i];
}
}
return result;
}
function curry(fn, ...args) {
var all = args || [];
return function (...rest) {
all.push(...rest);
if (rest.length == 0) {
return fn.apply(null, all);
} else {
return curry.call(null, fn, ...all);
}
};
}
var add2 = curry(add);
var cc = add2(1)(3)();
console.log(cc);