我写了一个函数:
function add(){
let arr = [];
arr = arr.concat(Array.prototype.slice.apply(arguments))
let fun = function(){
arr = arr.concat(Array.prototype.slice.apply(arguments))
return fun
}
fun.toString = function(){
console.log(222)
return arr.reduce(function(total, num){
return total+num
}, 0)
}
return fun
}
console.log(add(1,2)(2,3)(3))
这是在Chrome中:在此处输入图像描述
两个问题:
在第一行,为什么
'f 11'
,而不是'11'
?为什么输出
'f 11'
首先,而不是'222'
,我认为类型转换应该首先执行,然后在控制台上输出计算结果。
另一件奇怪的事情是,这是Firefox的结果,并具有相同的代码:在此处输入图像描述
和节点环境中的结果:在此处输入图像描述
我不明白为什么在ff和node中似乎没有执行计算的操作。
请帮助我...非常感谢!
首先,您可以稍微美化整个代码:
function add(..arr){
function fun(...args){
arr.push(...args);
return fun
}
fun.toString = function(){
return arr.reduce((total, num) => total + num)
};
return fun;
}
正如您正确注意到的那样,记录功能完全取决于环境。Firefox和Node返回函数的代码,而Chrome确实喜欢:
out( "f" + add.toString())
因此,我们的tostring函数被调用并记录了某些内容。为了在不同环境之间具有一致的行为,我们可以明确地称呼tostring:
console.log(add(1)(2)(3).toString());
可以推断出来:
console.log("" + add(1)(2));
如果您想要的是 add
,那既是variadic又是咖喱(我认为这很奇怪),请这样做:
const add = (...args) => {
let accum = args;
let f = (...fargs) => {
if (!fargs.length) {
return accum.reduce((a, b) => { return a + b; }, 0);
} else {
accum = accum.concat(fargs);
return f;
}
};
return f;
};
add(1,2,3)(); // 6
add(1)(2,3)(); // 6
add()(); // 0
现在,您只需调用返回的函数而没有参数即可将值删除。您可以使用它来使其更具性能(例如,在循环中使用.push
而不是.concat
),但这应该起作用。