要求: 实现函数sum(1)(2)(3) = 6;
方法一:
直接使用闭包:
function sum (a) {
return function (b) {
return function (c) {
return a + b + c;
}
}
}
缺点: 这种方法能够非常便捷的实现题设要求;但是,其自适应性太差;比如要实现sum(1)(2, 3),sum(1,2)(3),则需要重新修改函数;
方法二:
可以使用函数柯里化更加灵活的实现该函数:
function currying (fn) {
var outer = [].slice.call(arguments, 1); // 一般outer为空,也就是不向currying函数中传入fn函数的参数,这可以保证真正要操作的函数的相对独立性;如果想要在currying中传入fn的参数,可以将下边三行的注释去掉
//if (outer.length === len) {
// return fn.apply(null, outer);
//}
var len = fn.length;
return function () {
var inner = outer.concat([].slice.call(arguments));
return inner.length === len ? fn.apply(null, inner) : function () {
var args = inner.concat([].slice.call(arguments));
return args.length === len ? fn.apply(null, args) : function () {
var finalArgs = args.concat([].slice.call(arguments));
return fn.apply(null, finalArgs);
}
}
}
}
currying函数相当于一个工厂函数,需要实现柯里化的函数名作为参数传入后得到一个可以柯里化的函数,然后通过它进行真正的参数调用;
function multiply (a, b, c, d) {
return a * b * c * d;
}
var fn = currying(multiply);
fn(1,2)(3,4) //24
fn(1)(2,3,4) // 24
fn(1,2,3)(4) // 24
fn(1,2,3,4) // 24
fn(1)(2,3)(4) // 24
function currying (fn) {
var args = [].slice.call(arguments, 1);
var fun = function () {
if (arguments.length === 0) {
return fn.apply(this, args);
} else {
[].push.apply(args, arguments);
return fun;
}
}
return fun;
}
function add(){
return [].reduce.call(arguments, function(a,b){return a+b});
}
console.log(currying(add,1,2,3)(1)(2)(3,4,5,5)(5,6,6,7,8,8)(1)(1)(1)());//69