偏函数与函数柯里化
1. 偏函数
所谓偏函数,就是固定一个函数的一个或者多个参数,返回一个新的函数,这个函数用于接受剩余的参数。
1. 工厂方法
首先来看一个简单的例子:
1 2 3 4 5 6 7 8 9
| 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 方法封装成偏函数的形式来实现更加简洁的代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| 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 方法来实现偏函数
1 2 3 4 5 6 7 8 9 10 11
| function add(a, b) { return a + b; }
var parAdd = add.bind(null, 1);
parAdd(2); parAdd(3); parAdd(4); parAdd(5); parAdd(6);
|
2. 函数柯里化
柯里化是另一个有趣的处理函数技术。
柯里化(Currying):转换一个调用函数f(a,b,c)为f(a)(b)(c)方式调用。
下面实现了一个柯里化函数,执行一个两元参数函数,即转换f(a,b)至f(a)(b):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| 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. 无限加参
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
| 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);
|