-4

MDN 定义 reduce() 如下:

reduce() 方法对数组的每个元素执行一个 reducer 函数(由您提供),从而产生一个输出值。

我们不要想当然,只分析以下语句的语法:

const array1 = [1, 2, 3, 4];
const reducer = (y, x) => y + x;

// 1 + 2 + 3 + 4
console.log(array1.reduce(reducer));
// expected output: 10

// 5 + 1 + 2 + 3 + 4
console.log(array1.reduce(reducer, 5));
  1. reducer 是一个函数,它接受两个参数并返回它们的总和
  2. reducer 在数组的每个元素上执行,但“数组的每个元素”只是一个参数,为什么我可以假设 SUM 是另一个参数并缓存在某个地方等待下一次添加操作?为什么我可以假设 reduce 在最后返回总和?

有人可以回答这些问题吗?来自其他语言背景的人,例如也具有函数概念的 C。我经常对 Javascript 的语法感到困惑。

这就是我看到以下内容时变得更加困惑的原因:

const pipeline = [
  array => { array.pop(); return array; },
  array => array.reverse()
];

pipeline.reduce((xs, f) => f(xs), [1, 2, 3]);

因为根据 MDN,reduce() 方法再次对数组的每个元素执行一个 reducer 函数(您提供的),从而产生一个输出值。

只有这一次,

减速器:(xs, f) => f(xs)

累加器:[1,2,3]

array1:管道

那么我们如何解释它的行为类似于我们在英语中的第一个例子呢?

4

1 回答 1

0

reducer 在数组的每个元素上执行,但“数组的每个元素”只是一个参数,为什么我可以假设 SUM 是另一个参数并缓存在某个地方等待下一次添加操作?

提供的回调被多次调用,数组中的每个项目调用一次(或者,length - 1如果没有提供初始值,则多次调用)。您可以自己轻松实现:

const array1 = [1, 2, 3, 4];
const reducer = (y, x) => y + x;

Array.prototype.myReduce = function(callback, initialValue) {
  let accum = initialValue === undefined
    ? this.shift()
    : initialValue;
  for (let i = 0; i < this.length; i++) {
    accum = callback(accum, this[i], i, this);
  }
  return accum;
}
// 1 + 2 + 3 + 4
console.log(array1.myReduce(reducer));
// expected output: 10

// 5 + 1 + 2 + 3 + 4
console.log(array1.myReduce(reducer, 5));

仅仅因为您将一个函数传递给.reduce(或任何其他函数)并不会限制该函数可以调用多少次。

为什么我可以假设 reduce 在最后返回总和?

这就是方法的定义方式——就像上面的实现一样,累加器(或accum)在每次迭代时都被重新分配,并传递给回调的下一次调用。

该方法的浏览器本机实现实际上并没有像上面那样用 Javascript 编写,但它的功能是相同的(大部分情况下)。

pipeline工作方式相同。对于提供的数组的每个元素,累加器都被重新分配,并使用新的累加器调用下一个元素。这里,有一个函数数组被调用,每个函数的返回值被用作下一个累加器,最后一个函数调用返回的值是整个.reduce调用解析的值。

const pipeline = [
  array => { array.pop(); return array; },
  array => array.reverse()
];

pipeline.reduce((xs, f) => f(xs), [1, 2, 3]);

第 1 项:初始值(累加器)为 [1, 2, 3]。插入array => { array.pop(); return array; }.pop()的最后一个值(3,导致[1, 2],然后返回数组。

第 2 项:累加器(最后一次迭代的返回值)为[1, 2]. 将其插入array => array.reverse(),你会得到相同的数组,反转:[2, 1]

数组中没有更多的项目,所以这[2, 1]是整个reduce调用计算的值。

于 2019-07-01T03:41:28.120 回答