查看代码,只有一个可能的答案:由于您的函数counter
仅在传递给时被引用一次reduce()
,因此 reduce 必须为函数提供参数。
减少的工作原理
这是reduce如何工作的可视化。您需要从上到下阅读图表,/
并\
指出哪些参数(如下)传递给counter()
上面的函数。
return value of reduce()
/
etc ...
/
counter
/ \
counter xs[2]
/ \
counter xs[1]
/ \
0 xs[0]
counter()
最初提供了0
(毕竟,当您还没有处理任何元素时,看到的初始总数量为零)和第一个元素。
如果数组的第0
一个元素为零,则增加一。看到第一个元素后的新总数然后返回counter(0, xs[0])
给reduce()
函数。只要剩下元素,它就会将此值作为新的挂起总数传递给counter()
函数,以及数组中的下一个元素:xs[1]
。
只要数组中有元素,这个过程就会重复。
将此概念映射到代码
function reduce(combine, base, array) {
forEach(array, function (element) {
base = combine(base, element);
});
return base;
}
从图中可以看出,最初与 一起0
传递给函数,这表示构造内的第一次“迭代” 。然后将结果值写回.base
element
xs[0]
forEach
base
正如您在可视化中看到的,0
是函数的左参数counter()
,其结果随后作为左参数传递给counter()
。由于base/total
充当forEach
构造中的左参数,因此将该值写回 是有意义的base/total
,因此先前的结果将counter()/combine()
在下一次迭代时再次传递给。s的路径/
是 的“流” base/total
。
从哪里来element
_
从Eloquent JavaScript 的第 6 章开始,这里是forEach()
(在评论中,我action
用最终值替换了对的调用。)
function forEach(array, action) {
for (var i = 0; i < array.length; i++)
action(array[i]); // <-- READ AS: base = counter(base, array[i]);
}
action
表示一个函数,它在一个简单的for
循环中为每个元素调用,同时迭代array
.
在您的情况下,这是通过以下方式传递action
的forEach()
:
function (element) {
base = combine(base, element);
}
它是每次调用时定义的匿名函数reduce()
。每次迭代element
“真的”一次也是如此。array[i]
for