为什么reduce的回调函数需要四个参数?

Why does the callback function for reduce take four parameters?

在研究reduce方法的时候不太明白为什么传入的callback需要第三个和第四个参数,index和array。在来自 MDN 的示例中:

[0, 1, 2, 3, 4].reduce(function(previousValue, currentValue, index, array) {
  return previousValue + currentValue;
});

我研究过的数组 reduce 方法或下划线 reduce 函数的许多其他用途仅使用 callback 的前两个参数:previousValue(有时被视为 accumulator) 和 currentValue(又名 elem,当前索引的值)。

为什么reduce有时写成callback有四个参数,有时只写previousValuecurrentValue

什么情况下需要 indexarray 参数?

在 reduce 的应用程序需要第三个或第四个参数的情况下,是否应该始终在 reduce 的函数定义中给出所有四个参数?

如果您只需要使用前两个参数,那么将后两个参数留在函数参数列表中是完全可以的。在那种情况下,最后两个参数将被忽略。对数组求和,这是一种完全可以接受的方法:

[0, 1, 2, 3, 4].reduce(function(previousValue, currentValue) {
  return previousValue + currentValue;
});

最后两个参数 indexarray 只是在您需要时提供额外信息。例如,假设你想将数组中的所有元素乘以它们的镜像元素相加,也就是说,给定数组 [0, 1, 2, 3, 4] 你想要输出

(0 * 4) + (1 * 3) + (2 * 2) + (3 * 1) + (4 * 0)

那么你将不得不使用最后两个参数:

[0, 1, 2, 3, 4].reduce(function(previousValue, currentValue, index, array) {
  return previousValue + currentValue * array[array.length - index - 1];
});

诚然,这是一个有点做作的例子,但我很难想出一个看起来不做作的例子。无论如何,最后两个参数偶尔会派上用场。

这是一个(稍微)不那么做作的示例,使用 indexarray[=20 来总结数组中的唯一值,跳过重复项=] 用于查找唯一值的参数:

[0, 1, 2, 3, 2, 1, 0].reduce(function(previousValue, currentValue, index, array) {
  return array.indexOf(currentValue) === index ? // value used already?
         previousValue + currentValue :  // not used yet, add to sum
         previousValue; // used already, skip currentValue
}); // == 6  ( 0+1+2+3 )

现场演示:http://pagedemos.com/fn764n659ama/1/

旁注:[].reduce() 在 V8 中通过将所有四个参数指定为回调的形式参数来运行得更快,无论它们是否被函数内部的代码使用。