1、add(1)(3)(9) //输出13
function add(num){
var sum=0;
sum= sum+num;
return function(numB){
sum= sum+ numB;
return function(numC){
sum= sum+ numC;
return sum;
}
}
}
2、考虑其拓展性
可以发现返回的每一个函数执行的逻辑都是一样的,就此我们可以精简下代码,让函数返回后返回自身,哈哈这就是链式调用的写法,嗯嗯add(2)(3)(4)就是一个链式调用
function add(num){
var sum=0;
sum= sum+num;
return function tempFun(numB){
sum= sum+ numB;
return tempFun;
}
}
但是
var result=add(2)(3)(4)(5);
console.log(result);
并没有输出我们预料的结果14,而是一个函数的字符串表示,想想也不奇怪,你每次函数调用后返回的一个函数对象,那么console.log输出就是一个函数对象的字符串表示了。
那么怎么能把结果输出呢?
2种方法
第1种方法,在函数中添加判断,当没有输入参数时,直接返回调用的结果而不是返回函数
function add(num){
var sum=0;
sum= sum+num;
return function tempFun(numB){
if(arguments.length===0){
return sum;
}else{
sum= sum+ numB;
return tempFun;
}
}
}
调用时和前面的有点区别
var result=add(2)(3)(4)(5)();
console.log(result);//输出14
第2种方法利用JS中对象到原始值的转换规则
当一个对象转换成原始值时,先查看对象是否有valueOf方法,如果有并且返回值是一个原始值,
那么直接返回这个值,否则没有valueOf或返回的不是原始值,那么调用toString方法,返回字符串表示
我们就为函数对象添加一个valueOf方法和toString方法
function add(num){
var sum=0;
sum= sum+num;
var tempFun=function(numB){
if(arguments.length===0){
return sum;
}else{
sum= sum+ numB;
return tempFun;
}
}
tempFun.valueOf=function(){
return sum;
}
tempFun.toString=function(){
return sum+'';
}
return tempFun;
}
var result=add(2)(3)(4)(5);
console.log(+result);//输出14 valueOf
console.log(result);//输出14 toString
个人认为这样的写法很不好~函数调用语义不清晰
PS:还可以这样实现
var add=(function(){
var args=[];
function addInner(){
if(arguments.length===0){
return calResult;
}else{
Array.prototype.push.apply(args,Array.prototype.splice.call(arguments,0));
return add;
}
}
function calResult(){
var result=args.reduce(function(previousValue, currentValue){
return previousValue+currentValue;
},0);
args=[];
return result;
}
addInner.valueOf=function(){
return calResult();
};
addInner.toString=function(){
return calResult()+'';
};
return addInner;
}());
console.log('%d',add(1)(2)(3)(4));
function add(x) {
var sum = x;
var tmp = function (y) {
sum = sum + y;
return tmp;
};
tmp.toString = function () {
return sum;
};
return tmp;
}
console.log(add(1)(2)(3)); //6
console.log(add(1)(2)(3)(4)); //10