# 实现一个无限累加函数
问题:用 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;
}