Javascript &引用;加上「;用于不同链接/参数组合的函数

Javascript &引用;加上「;用于不同链接/参数组合的函数,javascript,Javascript,我正在尝试编写一个add函数,它可以在许多场景中工作 add(2,2,2) //6 add(2,2,2,2) //8 add(2)(2)(2) // 6 add(2)(2)(2,2).value() //8 add(2,2)(2) + 2 //8 add(2).add(2) //4 add(2,2,2).add(2).add(2,2).value() //12 add(2,2,2).add(2).value() //8 这就是我到目前为止所做的: 函数添加(){ var总和=0; for(参

我正在尝试编写一个add函数,它可以在许多场景中工作

add(2,2,2) //6
add(2,2,2,2) //8
add(2)(2)(2) // 6
add(2)(2)(2,2).value() //8
add(2,2)(2) + 2 //8
add(2).add(2) //4
add(2,2,2).add(2).add(2,2).value() //12
add(2,2,2).add(2).value() //8
这就是我到目前为止所做的:

函数添加(){
var总和=0;
for(参数中的变量i){
总和+=参数[i];
}
var ret=add.bind(null,sum);
ret.value=函数(){
回报金额;
}
ret.add=函数(){
for(参数中的变量i){
总和+=参数[i];
}
回报金额;
}
ret.valueOf=函数(){return sum;};
返回ret;
}
控制台日志(添加(2,2,2));
控制台日志(添加(2,2,2,2));
控制台日志(添加(2)(2)(2));
log(添加(2)(2)(2,2).value());
控制台日志(添加(2,2)(2)+2);
console.log(add(2).add(2));
log(add(2,2,2).add(2.value());

log(add(2,2,2).add(2).add(2,2).value())由于您在ret.add函数中返回总和,因此会出现错误。请尝试类似的操作,希望它能解决您的问题

function add(){
    var sum = 0;
    for( var i in arguments ){
        sum += arguments[i];
    }

    var ret = add.bind(null, sum);

    ret.value = function () {
      return sum;
    }

    ret.add = function () {
      for( var i in arguments ){
        sum += arguments[i];
      }
      return ret;
    }

    ret.valueOf = function(){ return sum; };

    return ret;
}
此外,它们还需要始终返回int(而不是字符串),似乎有时返回int,有时不返回int

是的,这绝对是一个概念上的问题。这两件你想要的东西是不相容的。
add(2,2,2)
是一个数字还是一个带有
add
方法的东西

add(2,2,2) //6
add(2,2,2).add(2).value() //8
即使有一种奇特的方式向numers添加方法,我还是强烈建议保持简单,并且始终需要一个“.value()”调用来结束链。这样,对“.add”的所有调用返回一个“adder对象”,对“.value”的所有调用返回一个常规数字

如果我想将两个以上的add函数链接在一起,并将value函数添加到它们中的每一个,那么我似乎必须继续嵌套add函数,但显然我缺少了一些简单的东西,可以让我尽可能多地链接它们,并对它们中的任何一个调用value

答案是使用递归函数。下面是一个创建我前面提到的“加法器”对象的函数:

function sumArray(arr){
    var s = 0;
    for(var i=0; i<arr.length; i++){
        s += arr[i];
    }
    return s;
}

function mkAdder(currSum){
    return {
        value: function(){
            return currSum;
        },
        valueOf: function(){
            return currSum;
        },
        add: function(/**/){
            return mkAdder(currSum + sumArray(arguments));
        }
    }
}

看看你在两个不同的地方以相似的方式使用
参数的方式,很明显你是在复制功能,这就是为什么你不得不“无限嵌套”
.value()
方法而遇到这个问题的原因

要认识到的关键是
add()
可以返回一个函数,该函数将自身引用为自己的
add
属性。这将允许
add(1,2)(3)
的行为与
add(1,2).add(3)
完全相同。可以这样做:

函数添加(){
var sum=Array.prototype.reduce.call(参数,函数(l,r){
返回l+r;
}, 0);
var ret=add.bind(null,sum);
ret.add=ret;
ret.value=ret.valueOf=Number.prototype.valueOf.bind(总和);
ret.toString=Number.prototype.toString.bind(总和);
返回ret;
}
log(添加(2,2,2));
log(添加(2,2,2,2));
log(添加(2)(2)(2));
log(添加(2)(2)(2,2).value());
log(添加(2,2)(2)+2);
log(添加(2).add(2));
log(add(2,2,2).add(2.value());
log(add(2,2,2).add(2).add(2.2).value());
log(添加(1,2,3)(4,5).add(6,7)(8).add(9,10));
日志(添加(5,4)(3)。添加(2)(1)*10)

我试着即兴使用
这个
。适用于所有情况

function add(){
    var sum =  this instanceof Number?this: 0;
    for( var i in arguments ){
        sum += arguments[i];
    }

    var ret = add.bind(sum);
    ret.add = ret;
    ret.value = ret.valueOf = function() { return sum; };

    ret.toString = sum.toString.bind(sum);

    return ret;
}

顺便说一句,不要使用“for-in”循环来迭代数组,因为for-in循环没有保证的迭代顺序,它还可以迭代非整数属性。使用常规的
,用于(i=0,iYou正试图在这里做很多事情。作为一个学习练习,这可能很有趣,但我真的希望您不要试图在闲置的实验之外使用它。这种可笑的、棘手的语法重载在现实世界的代码中没有位置。如果您真的需要它,您可以将函数添加到数字原型中。或者创建一个自定义wr扩展Number对象以便不弄脏原始原型的apper。不太清楚为什么不能只使用
+
尽管..@hugomg尽管还要注意,
参数
不是数组,而是类似数组的对象。这肯定是一个练习,+运算符就足够了:P
sum.toString.bind(sum)
?聪明。我想知道你为什么不对
valueOf
…@Bergi做同样的事情,因为它需要一个不必要的装箱操作,但这可能只是不必要的优化,以及
sum.toString.bind(sum)
还涉及不必要的装箱。此处的
add
方法的实现引入了不一致性,因为它有副作用:
function add(){
    var sum =  this instanceof Number?this: 0;
    for( var i in arguments ){
        sum += arguments[i];
    }

    var ret = add.bind(sum);
    ret.add = ret;
    ret.value = ret.valueOf = function() { return sum; };

    ret.toString = sum.toString.bind(sum);

    return ret;
}