首页 > 解决方案 > 通过 Apply 调用函数与从 Currying 函数直接调用

问题描述

我正在尝试实现柯里化功能:

function sum(a, b, c) {
console.log('SUM'+JSON.stringify(arguments))
  return a + b + c;
}

var curry= function (func,...n) {
      return function(...args2) {
         //console.log('arg2s'+args2)
        return func.apply(this,n.concat(args2));


  };

}

curry(sum,1,2)(3) //SUM{"0":1,"1":2,"2":3}, O/P:6

上面给出了正确的输出,但我没有必要使用 apply。

所以,如果我将我的功能更改为以下:

var curry= function (func,...n) {
      return function(...args2) {
         //console.log('arg2s'+args2)
        return func(n.concat(args2));


  };

}
curry(sum,1,2)(3) //SUM{"0":[1,2,3]}  O/P:"1,2,3undefinedundefined"

我在这里基本上有两个问题:

  1. 为什么直接调用func时curry的实现不起作用?为什么输出这么奇怪?

2.如何改变我的函数,我可以如下调用它并返回总和:curry(1)(2)(3)/curry(1,2)(3)/curry(1,2, 3)等,而不是我目前打电话的方式。我可以在网上找到一些解决方案,但无法理解。

前任:

function curry(func) {

  return function curriedFunc(...args) {
    if (args.length >= func.length) {
      return func.apply(this, args);
    } else {
      return function(...args1) {
        return curriedFunc.apply(this, args.concat(args1));
      }
    }
  };

}

任何帮助将不胜感激!

标签: javascriptscopecurrying

解决方案


func接受三个参数:abc。当你这样做时:

return func(n.concat(args2));

你传递给它一个参数,一个数组。它相当于:

const arr = n.concat(args2);
return func(arr);

听起来你想将参数传播到调用中func

return func(...n, ...args2)

使用扩展语法,可迭代的每个项目都放入一个参数中。例如,如果n数组有一个项目,则将其设置为传递给 的第一个参数func,如果args2有 2 个项目,则将第一个设置为传递的第二个参数,将第二个设置为传递的第三个参数。

function sum(a, b, c) {
  console.log('SUM' + JSON.stringify(arguments))
  return a + b + c;
}

var curry = function(func, ...n) {
  return function(...args2) {
    return func(...n, ...args2);
  };

}
curry(sum, 1, 2)(3);

我如何以一种我可以如下调用它并应该返回总和的方式更改我的函数:curry(1)(2)(3)/curry(1,2)(3)/curry(1,2,3) ETC

跟踪第一次调用函数时创建的闭包中传递的参数总数。在返回的函数中,将所有参数压入数组,如果数组的长度为3,则返回和,否则再次返回函数:

function sum(a, b, c) {
  return a + b + c;
}

var curry = function(func, ...argsSoFar) {
  const neededArgs = func.length;
  const returnedFn = (...args) => {
    argsSoFar.push(...args);
    if (argsSoFar.length === neededArgs) {
      return func(...argsSoFar);
    } else {
      return returnedFn;
    }
  };
  return returnedFn;
}
console.log(
  curry(sum, 1, 2)(3),
  curry(sum)(1, 2)(3),
  curry(sum)(1)(2, 3),
  curry(sum)(1)(2)(3),
);


推荐阅读