繁体   English   中英

在函数数组上执行Javascript'reduce'如何实现函数组合?

[英]How Javascript `reduce` performed on function array achieves function composition?

我在redux compose功能中遇到了这种模式。 我仍然不明白如何在下面的示例中从最后开始而不是从第一个开始评估函数:

function f2(a) {
  return a + a;
}
function f3(a) {
  return a + a + a;
}
function f4(a) {
  return a + a + a + a;
}
function f5(a) {
  return a + a + a + a + a;
}

function compose(...funcs) {
  return funcs.reduce(function x(a, b) {
    return function y(...args) {
      const temp = a(b(...args));
      return temp;
    };
  });
}

const composedFunction = compose(f2, f3, f4, f5);
const result = composedFunction(2);

在第一个reduce迭代中,累加器为f2因此我们得到f2(f3(2))=12 在下一次迭代中,我们将调用f4(12)=48 在上一次迭代中,我们将调用f5(48)=240 因此,评估顺序为f5(f4(f2(f3(2)))) 但是使用console.log我看到评估顺序是f2(f3(f4(f5(2)))) ,巧合的也是240。

据我了解,函数y是为所有数组元素调用的,那么为什么只有最后一个函数将2作为参数?

让我们通过一个非常简单的示例逐步完成代码:

 compose(f2, f3, f4)

由于没有传递任何初始值来减少值,因此它将以数组的第一个(f2)和第二个(f3)值开头,并以该值调用回调, x的调用为af2bf3 现在x不执行任何操作,只返回可以通过闭包访问a和b的函数y

Reduce现在将继续到第三个元素,第一个参数是上一个回调(闭包y )的结果,第二个参数是f4 现在再次调用x ,并在y上创建另一个闭包, y从整个函数中最终返回。

如果我们尝试可视化这样的闭包函数,它将是:

 y { // closure of y
  a -> y { // a references another closure of y
    a -> f3,
    b -> f2
  },
  b -> f4
}

现在,您调用该闭包y并将2传递给它,这将调用bf4 )并将结果传递给该调用到a (闭包y)。

 a         (  b(...args))   
 y { ... } (  f4(2) )

现在,封闭的y将执行相同的操作:

 a (  b ( ...args))
 f2( f3( f4( 2 ) ) )

提示:有时很难跟踪闭包的值,因此控制台为您提供了强大的实用程序来跟踪它们:在控制台的“ debugger”选项卡中打开代码,单击函数调用所在的行号。附加断点,然后再次运行代码,只要到达断点,执行就会产生,您可以看到所有变量(包括封闭变量)的值。

reduce不会调用函数f2,f3,f3,f5,而是从这些函数创建函数。 这是每次迭代中累加器的值。 请注意,该值是一个function而不是function执行的结果。

1:a = f2; b = f3;返回值(不是温度,但函数y)= f2(f3(... args))

2:a(上一个返回值)= f2(f3(... args)); b = f4;返回值= f2(f3(f4(... args))))

等等....

撰写功能可以重写为:

function compose(...funcs) {
  return funcs.reduce(function (a, b) {
    return function (arg) {
      const temp = a(b(arg));
      return temp;
    };
  });
}

第一次迭代后,作为下一个累加器传递的返回函数为:

function (arg) {       // R1
  return f2(f3(arg));

}

在第二次迭代之后,作为下一个累加器传递的返回函数为:

function (arg) {       // R2
  return R1(f4(arg));

}

最后,分配给compositionFunction的返回函数为:

function (arg) {       // composedFunction
  return R2(f5(arg));

}

因此,运行composedFunction(2)并返回上链:

f5(2) returns 10

R2(10) returns R1(f4(10))
which is       R1(40)

R1(40) returns f2(f3(40))
which is   f2(120)
which is   240

希望这足够了。

可以将其写为以下单个调用:

function composedFunction(arg) {
  return f2(f3(f4(f5(arg))));
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM