我需要一个js sum函数才能像这样工作:
sum(1)(2) = 3
sum(1)(2)(3) = 6
sum(1)(2)(3)(4) = 10
etc.
我听说无法做到。但是听说如果在+
前面添加sum
就可以了。
像+sum(1)(2)(3)(4)
一样。
有关如何做到这一点的想法吗?
答案 0 :(得分:61)
不确定我是否理解你想要的东西,但是
function sum(n) {
var v = function(x) {
return sum(n + x);
};
v.valueOf = v.toString = function() {
return n;
};
return v;
}
console.log(+sum(1)(2)(3)(4));
答案 1 :(得分:13)
这是一个在最后一次调用中使用空括号作为关键键的例子(来自我上次的采访):
和(1)(4)(66)(35)(3)()
function sum(numberOne) {
var count = numberOne;
return function by(numberTwo) {
if (numberTwo === undefined) {
return count;
} else {
count += numberTwo;
return by;
}
}
}
console.log(sum(1)(4)(66)(35)(3)());

答案 2 :(得分:6)
我发布此修订版本作为自己的帖子,因为我显然没有足够的声誉,只是留下它作为评论。这是对@Rafael优秀解决方案的修订。
function sum (n) {
var v = x => sum (n + x);
v.valueOf = () => n;
return v;
}
console.log(+sum(1)(2)(3)(4)); //10
我没有看到保留v.toString位的原因,因为它似乎没有必要。如果我错误地这样做,请在评论中告诉我为什么需要v.toString(它没有通过我的测试就好了)。将其余的匿名函数转换为箭头函数以便于阅读。
答案 3 :(得分:2)
简洁的ES6新方式。
要终止呼叫并获得最终值,必须在末尾传递空()。
const sum= x => y => (y !== undefined) ? sum(x + y) : x;
这样称呼-
sum(10)(30)(45)();
答案 4 :(得分:1)
您可以使用以下功能
function add(num){
add.sum || (add.sum = 0) // make sure add.sum exists if not assign it to 0
add.sum += num; // increment it
return add.toString = add.valueOf = function(){
var rtn = add.sum; // we save the value
return add.sum = 0, rtn // return it before we reset add.sum to 0
}, add; // return the function
}
由于函数是对象,我们可以向其添加属性,我们在访问它时会重置它们。
答案 5 :(得分:1)
这是一个使用ES6和toString
的解决方案,类似于@Vemba
function add(a) {
let curry = (b) => {
a += b
return curry
}
curry.toString = () => a
return curry
}
console.log(add(1))
console.log(add(1)(2))
console.log(add(1)(2)(3))
console.log(add(1)(2)(3)(4))

答案 6 :(得分:1)
尝试一下
function sum (...args) {
return Object.assign(
sum.bind(null, ...args),
{ valueOf: () => args.reduce((a, c) => a + c, 0) }
)
}
console.log(+sum(1)(2)(3,2,1)(16))
在这里您可以看到有关带无限制参数的带载函数的中篇文章
https://medium.com/@seenarowhani95/infinite-currying-in-javascript-38400827e581
答案 7 :(得分:0)
要使sum(1)
可调用为sum(1)(2)
,它必须返回一个函数。
可以调用该函数或将其转换为valueOf
的数字。
function sum(a) {
var sum = a;
function f(b) {
sum += b;
return f;
}
f.toString = function() { return sum }
return f
}
答案 8 :(得分:0)
另一种略短的方法:
const sum = a => b => b? sum(a + b) : a;
可用作:
console.log(
sum(1)(2)(),
sum(3)(4)(5)()
);
答案 9 :(得分:0)
function add(a) {
let curry = (b) => {
a += b
return curry;
}
curry[Symbol.toPrimitive] = (hint) => {
return a;
}
return curry
}
console.log(+add(1)(2)(3)(4)(5)); // 15
console.log(+add(6)(6)(6)); // 18
console.log(+add(7)(0)); // 7
console.log(+add(0)); // 0
答案 10 :(得分:0)
这是ES6 Javascript中具有通用可变参数咖喱函数的解决方案,但需要注意的是,需要最后一个()
来调用参数:
const curry = (f) =>
(...args) => args.length? curry(f.bind(0, ...args)): f();
const sum = (...values) => values.reduce((total, current) => total + current, 0)
curry(sum)(2)(2)(1)() == 5 // true
这里是另一个不需要()
的地方,像@rafael's answer一样使用valueOf
。我觉得以这种方式使用valueOf
(或者可能根本不使用)对于阅读您的代码的人非常困惑,但是每个人都是自己的。
该答案中的toString
是不必要的。在内部,当javascript执行类型强制转换时,它总是在调用valueOf()
之前先调用toString()
。
// invokes a function if it is used as a value
const autoInvoke = (f) => Object.assign(f, { valueOf: f } );
const curry = autoInvoke((f) =>
(...args) => args.length? autoInvoke(curry(f.bind(0, ...args))): f());
const sum = (...values) => values.reduce((total, current) => total + current, 0)
curry(sum)(2)(2)(1) + 0 == 5 // true
答案 11 :(得分:0)
可能是一个古老的问题,但答案有点扩展
function sum() {
var args = [];
args.push(...arguments);
function sumOfAllArguments() {
return args.reduce((prev,items)=>prev + items, 0)
}
function v() {
arguments && args.push(...arguments);
return arguments.length === 0 ? sumOfAllArguments() : v;
}
v.valueOf = v.toString = sumOfAllArguments;
return v;
}
console.log(sum(2)(2)(2)()) // 6
console.log(sum(2)(2)(2).toString()) // 6
console.log(sum(2)(2)(2).valueOf()) // 6
console.log(+sum(2)(2)(2)) //6
console.log(sum(2)(2)(2)) // f 6
console.log(sum(2,2,2)(2,2)(2)) // f 12
console.log(sum(2)(2,2)(2)()) // 8
答案 12 :(得分:0)
这是一种更通用的解决方案,也适用于非一元参数:
const sum = function (...args) {
let total = args.reduce((acc, arg) => acc+arg, 0)
function add (...args2) {
if (args2.length) {
total = args2.reduce((acc, arg) => acc+arg, total)
return add
}
return total
}
return add
}
document.write( sum(1)(2)() , '<br/>') // with unary params
document.write( sum(1,2)() , '<br/>') // with binary params
document.write( sum(1)(2)(3)() , '<br/>') // with unary params
document.write( sum(1)(2,3)() , '<br/>') // with binary params
document.write( sum(1)(2)(3)(4)() , '<br/>') // with unary params
document.write( sum(1)(2,3,4)() , '<br/>') // with ternary params
答案 13 :(得分:-1)
在查看了此处的其他一些解决方案后,我想针对此问题提供我的两种解决方案。
使用 ES6 柯里化两个项目:
const sum = x => y => (y !== undefined ) ? +x + +y : +x
sum(2)(2) // 4
这里我们指定了两个参数,如果第二个不存在,我们只返回第一个参数。
对于三个或更多项目,它变得有点棘手;这是我的解决方案。对于任何其他参数,您可以将它们添加为第三个
const sum = x => (y=0) => (...z) => +x + +y + +z.reduce((prev,curr)=>prev+curr,0)
sum(2)()()//2
sum(2)(2)()//4
sum(2)(2)(2)//6
sum(2)(2)(2,2)//8
我希望这对某人有帮助
答案 14 :(得分:-1)
这是使用迭代过程的另一种功能方式
const sum = (num, acc = 0) => {
if (!num) return acc;
return x => sum(x, acc + num)
}
sum(1)(2)(3)()
单行
const sum = (num, acc = 0) => !num ? acc : x => sum(x, acc + num)
sum(1)(2)(3)()
答案 15 :(得分:-1)
let add = (a) => {
let sum = a;
funct = function(b) {
sum += b;
return funct;
};
Object.defineProperty(funct, 'valueOf', {
value: function() {
return sum;
}
});
return funct;
};
console.log(+add(1)(2)(3))
答案 16 :(得分:-1)
function sum(a){
let res = 0;
function getarrSum(arr){
return arr.reduce( (e, sum=0) => { sum += e ; return sum ;} )
}
function calculateSumPerArgument(arguments){
let res = 0;
if(arguments.length >0){
for ( let i = 0 ; i < arguments.length ; i++){
if(Array.isArray(arguments[i])){
res += getarrSum( arguments[i]);
}
else{
res += arguments[i];
}
}
}
return res;
}
res += calculateSumPerArgument(arguments);
return function f(b){
if(b == undefined){
return res;
}
else{
res += calculateSumPerArgument(arguments);
return f;
}
}
}