将额外的vs一个参数传递给函数

时间:2019-05-31 22:01:54

标签: javascript

我正在使用reduceRight方法实现撰写功能,如下所示

const compose = fns => (...args) =>
  fns.reduceRight((acc, fn) => fn(acc, ...[args.slice(1)]), args[0]);

const func3 = (x, y) => (y > 0 ? x + 3 : x - 3);

const func2 = x => x ** 2;

const func1 = x => x - 8;

const fnOne = compose([func1, func2, func3])('3', 1);
console.log(fnOne); // should be 1081

const fnTwo = compose([func1, func2, func3])('3', -1);
console.log(fnTwo); //should be -8

第一个函数应该接收两个参数,并将结果作为唯一一个参数返回给下一个函数。问题在于第一个函数将两个参数传递给下一个函数而不是一个。让我知道您是否有解决办法。非常感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

您需要在reduceRight()循环之外调用第一个函数,因为与所有其他函数的调用方式不同。它从...args获取其参数,其值应用作reduce的初始累加器参数。

const compose = fns => (...args) => {
  let last = fns.pop();
  return fns.reduceRight((acc, fn) => fn(acc), last(...args))
};

const func3 = function(x, y) {
  console.log(`func3 got ${arguments.length} arguments`);
  return (y > 0 ? x + 3 : x - 3);
};

const func2 = function(x) {
  console.log(`func2 got ${arguments.length} arguments`);
  return x ** 2;
};

const func1 = function(x) {
  console.log(`func2 got ${arguments.length} arguments`);
  return x - 8;
};

const fnOne = compose([func1, func2, func3])('3', 1);
console.log(fnOne); // should be 1081

const fnTwo = compose([func1, func2, func3])('3', -1);
console.log(fnTwo); //should be -8

答案 1 :(得分:1)

这里的问题是您没有修改args变量。

让我们详细看看发生了什么:

在您的归约器的第一次呼叫中,acc变成func3(args[0], ...[args.shift(1)]) === func3(args[0], args[1], args[2], ...)

在第二个呼叫中,acc变成func2(acc, [args.shift(1)]),即func2(func3(args[0], args[1], args[2], ...), args[1], args[2], ...)

您已经知道问题出在哪里:args1从未从数组中删除,因为Array.slice()创建了一个副本,并且没有修改实际的数组。

要解决您的问题,您应该使用:

const compose = fns => (...args) =>
  fns.reduceRight((acc, fn) => fn(acc, ...args.splice(0, fn.length - 1)), args[0]);