# 实现一个无限累加函数

问题:用 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;
}