Javascript &引用;加上「;用于不同链接/参数组合的函数
我正在尝试编写一个add函数,它可以在许多场景中工作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(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尽管还要注意,参数
不是数组,而是类似数组的对象。这肯定是一个练习,+运算符就足够了:Psum.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;
}