我正在尝试编写一个在许多情况下都可以工作的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这就是我到目前为止所知道的:
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 sum;
}
ret.valueOf = function(){ return sum; };
return ret;
}
console.log(add(2,2,2));
console.log(add(2,2,2,2));
console.log(add(2)(2)(2));
console.log(add(2)(2)(2,2).value());
console.log(add(2,2)(2) + 2);
console.log(add(2).add(2));
console.log(add(2,2,2).add(2).value());
console.log(add(2,2,2).add(2).add(2,2).value());
我对最后两个案例有个问题:
add(2,2,2).add(2).add(2,2).value() //12
add(2,2,2).add(2).value() //8如果我想要将两个以上的函数链接在一起,并将value函数添加到每个函数中,那么我似乎必须继续嵌套add函数,但显然我遗漏了一些简单的东西,可以让我尽可能多地链接它们,并对它们中的任何一个调用value。
此外,它们需要总是返回it (而不是字符串),而且似乎有时返回,有时不返回?
发布于 2015-03-08 22:50:41
看一下您在两个不同的地方以类似的方式使用arguments的方式,很明显您是在复制功能,这就是为什么您会遇到这个问题,因为您必须“无限嵌套”.value()方法。
要认识到的关键一点是,add()可以返回一个函数,该函数将自身引用为自己的add属性。这将允许add(1,2)(3)的行为与add(1,2).add(3)完全相同。这可以像这样做:
function add() {
var sum = Array.prototype.reduce.call(arguments, function(l, r) {
return l + r;
}, 0);
var ret = add.bind(null, sum);
ret.add = ret;
ret.value = ret.valueOf = Number.prototype.valueOf.bind(sum);
ret.toString = Number.prototype.toString.bind(sum);
return ret;
}
snippet.log(add(2,2,2));
snippet.log(add(2,2,2,2));
snippet.log(add(2)(2)(2));
snippet.log(add(2)(2)(2,2).value());
snippet.log(add(2,2)(2) + 2);
snippet.log(add(2).add(2));
snippet.log(add(2,2,2).add(2).value());
snippet.log(add(2,2,2).add(2).add(2,2).value());
snippet.log(add(1, 2, 3)(4, 5).add(6, 7)(8).add(9, 10));
snippet.log(add(5,4)(3).add(2)(1) * 10);<!-- Provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
上述方法仍然存在两个潜在问题,一个较小,另一个稍小一些:
add函数时(包括链接期间)都会重新执行属性引用和函数定义add标识符,则会导致整个实现中断:
function add() {
var sum = Array.prototype.reduce.call(arguments, function(l, r) {
return l + r;
}, 0);
var ret = add.bind(null, sum);
ret.add = ret;
ret.value = ret.valueOf = Number.prototype.valueOf.bind(sum);
ret.toString = Number.prototype.toString.bind(sum);
return ret;
}
var myAdd = add;
add = "boom!";
myAdd(1, 2, 3); // TypeError: add.bind is not a function
这两个问题都可以用生命来弥补:
var add = (function () {
var reduce = Array.prototype.reduce,
np = Number.prototype,
valueOf = np.valueOf,
toString = np.toString,
plus = function (l, r) { return l + r; };
return function add() {
var sum = reduce.call(arguments, plus, 0);
var ret = add.bind(null, sum);
ret.add = ret;
ret.value = ret.valueOf = valueOf.bind(sum);
ret.toString = toString.bind(sum);
return ret;
}
})();
var myAdd = add;
add = "U Can't Touch This"; // hammertime
snippet.log(myAdd(1, 2, 3)(4, 5).add(6, 7)(8).add(9, 10));
snippet.log(myAdd(5,4)(3).add(2)(1) * 10);<!-- Provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
发布于 2015-03-08 23:12:06
我试着即兴使用this。适用于所有情况。
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;
}发布于 2015-03-08 22:33:32
既然您在ret.add函数中返回了sum,这就是错误出现的原因,请尝试如下所示,希望它能解决您的问题
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;
}https://stackoverflow.com/questions/28927510
复制相似问题