# 实现一个无限累加函数
问题:用 JS 实现一个无限累加的函数 add,示例如下:
add(1); // 1
add(1)(2); // 3
add(1)(2)(3); // 6
add(1)(2)(3)(4); // 10
// 以此类推
实现:
function add(a) {
function sum(b) { // 使用闭包
a = b ? a + b : a; // 累加
return sum;
}
sum.toString = function() { // 只在最后一次调用
return a;
}
return sum; // 返回一个函数
}
add(1) // 1
add(1)(2) // 3
add(1)(2)(3) // 6
add(1)(2)(3)(4) // 10
我们知道打印函数时会自动调用toString()方法,函数add(a)返回一个闭包sum(b),函数sum()中累加计算 a = a + b,只需要重写sum.toString()方法返回变量 a 就OK了。
这样说才能理解:
add(10): 执行函数add,注意这一次没有调用sum,所以只是返回了sum,再执行sum.toString方法。所以输出10;
add(10)(20): 执行函数add(10),返回sum(此时a为10),再执行sum(20),此时a为30,返回sum,最后调用sum.toString()输出30。 add(10)(20)...(n)依次类推。
来个升级版, 实现多参数传递累加
add(1)(3,4)(3,5) // 16
add(2)(2)(3,5) // 12
function add () {
let args = Array.prototype.slice.call(arguments);
let fn = function () {
let arg_fn = Array.prototype.slice.call(arguments);
return add.apply(null, args.concat(arg_fn));
}
fn.toString = function(){
args.reduce(function(a, b){
return a + b
})
}
return fn;
}
// es6
function add () {
let args = [...arguments];
let fn = function(){
return add.apply(null, args.concat([...arguments]))
}
fn.toString = () => args.reduce((a, b) => a + b)
return fn;
}