可变咖喱求和函数

IT技术 javascript currying
2021-02-03 22:11:19

我需要一个 js sum 函数才能像这样工作:

sum(1)(2) = 3
sum(1)(2)(3) = 6
sum(1)(2)(3)(4) = 10 
etc.

听说做不到 不过听说如果+在前面加上sum就可以了。喜欢+sum(1)(2)(3)(4)
关于如何做到这一点的任何想法?

6个回答

不确定我是否理解你想要的,但是

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));

JsFiddle

@maverick 不,valueOf由 JavaScript 内部调用,例如在运行一元运算+符时。根据 ES5 规范,+运行 abstract ToNumber,后者又调用 abstract ToPrimitive,后者调用内部方法 `[[DefaultValue]]`,最终调用valueOf. 您可以从这里开始遵循调用链
2021-03-16 22:11:19
@Yaroslav:如果将结果转换为字符串(例如使用 alert() 时),它将起作用。使用原生console.log时,会看到function () { return n + x; 在控制台中。
2021-03-23 22:11:19
函数调用前的 + 是什么意思?
2021-03-27 22:11:19
顺便说一句,Firefox 不需要 + 来执行转换:-)。你可以不调用它,它会起作用。
2021-03-31 22:11:19
+ 将 sum() 的结果转换为数字。在这种情况下,JavaScript 会调用对象的 .valueOf 方法。由于我返回匿名函数,这有助于将其转换为原始类型。正如你所看到的,我用我自己的覆盖了原生的 .valueOf 。
2021-04-01 22:11:19

这是在最后一次调用中使用空括号作为关闭键的示例(来自我上次采访):

总和(1)(4)(66)(35)(0)()

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)(0)());

太感谢了。我正在为这个答案敲我的头。如果你能解释这背后的逻辑以及它是如何工作的,我会很高兴的?
2021-03-17 22:11:19

我将此修订版作为自己的帖子发布,因为我显然还没有足够的声誉来将其作为评论。这是@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(没有它它通过了我的测试)。将其余的匿名函数转换为箭头函数以方便阅读。

toString意味着console.log("The result is " + sum(1) + "!")正常工作
2021-03-26 22:11:19
console.log("The result is " + sum(1) + "!")​The result is 1!即使函数中toStringv.valueOf语句中省略了 ,返回字符串sum,就像我上面所做的那样。仍然不清楚添加什么toString会完成尚未发生的事情。
2021-04-07 22:11:19

这是一个使用 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))

新的 ES6 方式并且简洁。

当你想终止调用并获得最终值时,你必须在最后传递 empty() 。

const sum= x => y => (y !== undefined) ? sum(x + y) : x;

像这样称呼它-

sum(10)(30)(45)();
好的!它允许多个参数在每一步的变体,比如sum (3, 4, 5) (22) (2, 6) () //=> 42,可能看起来像这样:const sum = (...xs) => (...ys) => ys .length ? sum (...xs, ...ys) : xs .reduce ((a, b) => a + b, 0)
2021-04-07 22:11:19