Array.prototype.reduceRight()

基线 广泛可用

此功能已得到良好建立,并且可以在许多设备和浏览器版本中使用。它自以下时间起在各个浏览器中可用 2015 年 7 月.

reduceRight()Array 实例的 迭代方法,它将一个函数应用于累加器和数组的每个值(从右到左),将其减少为单个值。

另请参阅 Array.prototype.reduce() 以了解从左到右的操作。

试一试

语法

js
reduceRight(callbackFn)
reduceRight(callbackFn, initialValue)

参数

callbackFn

要为数组中每个元素执行的函数。其返回值成为 callbackFn 下次调用时 accumulator 参数的值。对于最后一次调用,返回值成为 reduceRight() 的返回值。该函数使用以下参数调用

accumulator

来自 callbackFn 上次调用的结果值。在第一次调用时,如果指定了后者,则其值为 initialValue;否则其值为数组的最后一个元素。

currentValue

当前元素的值。在第一次调用时,如果指定了 initialValue,则其值为最后一个元素;否则其值为倒数第二个元素。

currentIndex

currentValue 在数组中的索引位置。在第一次调用时,如果指定了 initialValue,则其值为 array.length - 1,否则为 array.length - 2

array

调用 reduceRight() 的数组。

initialValue 可选

用作累加器以进行 callbackFn 的第一次调用的值。如果未提供初始值,则将使用并跳过数组中的最后一个元素。在没有初始值的情况下对空数组调用 reduceRight() 会创建 TypeError

返回值

归约产生的值。

描述

reduceRight() 方法是 迭代方法。它以降序索引顺序对数组中的所有元素运行“归约器”回调函数,并将它们累积到单个值中。阅读 迭代方法 部分,以获取有关这些方法如何普遍工作的更多信息。

callbackFn 仅对具有赋值的数组索引调用。它不会对 稀疏数组 中的空插槽调用。

与其他 迭代方法 不同,reduceRight() 不接受 thisArg 参数。callbackFn 始终使用 undefined 作为 this 调用,如果 callbackFn 非严格,则将其替换为 globalThis

reduceRight() 方法是 泛型。它仅期望 this 值具有 length 属性和整数键属性。

何时不使用 reduce() 中讨论的关于 reduce 的所有注意事项也适用于 reduceRight。因为 JavaScript 没有惰性求值语义,所以 reducereduceRight 之间没有性能差异。

示例

reduceRight() 在没有初始值的情况下如何工作

对 reduceRight callbackFn 的调用看起来像这样

js
arr.reduceRight((accumulator, currentValue, index, array) => {
  // …
});

函数第一次被调用时,accumulatorcurrentValue 可以是两个值之一。如果在对 reduceRight 的调用中提供了 initialValue,则 accumulator 将等于 initialValue,而 currentValue 将等于数组中的最后一个值。如果未提供 initialValue,则 accumulator 将等于数组中的最后一个值,而 currentValue 将等于倒数第二个值。

如果数组为空且未提供 initialValue,则会抛出 TypeError。如果数组只有一个元素(无论位置如何)并且未提供 initialValue,或者提供了 initialValue 但数组为空,则会返回单独的值,而不会调用 callbackFn

函数的一些示例运行过程如下所示

js
[0, 1, 2, 3, 4].reduceRight(
  (accumulator, currentValue, index, array) => accumulator + currentValue,
);

回调将被调用四次,每次调用的参数和返回值如下所示

accumulator currentValue 索引 返回值
第一次调用 4 3 3 7
第二次调用 7 2 2 9
第三次调用 9 1 1 10
第四次调用 10 0 0 10

array 参数在整个过程中从未改变——它始终为 [0, 1, 2, 3, 4]reduceRight 返回的值将是最后一次回调调用的值(10)。

reduceRight() 如何使用初始值

在这里,我们使用相同的算法减少相同的数组,但将 initialValue 的值为 10 作为第二个参数传递给 reduceRight()

js
[0, 1, 2, 3, 4].reduceRight(
  (accumulator, currentValue, index, array) => accumulator + currentValue,
  10,
);
accumulator currentValue 索引 返回值
第一次调用 10 4 4 14
第二次调用 14 3 3 17
第三次调用 17 2 2 19
第四次调用 19 1 1 20
第五次调用 20 0 0 20

这次 reduceRight 返回的值当然将是 20

汇总数组中的所有值

js
const sum = [0, 1, 2, 3].reduceRight((a, b) => a + b);
// sum is 6

按顺序运行一系列异步函数,每个函数都将结果传递给下一个函数

js
const waterfall =
  (...functions) =>
  (callback, ...args) =>
    functions.reduceRight(
      (composition, fn) =>
        (...results) =>
          fn(composition, ...results),
      callback,
    )(...args);

const randInt = (max) => Math.floor(Math.random() * max);

const add5 = (callback, x) => {
  setTimeout(callback, randInt(1000), x + 5);
};
const mult3 = (callback, x) => {
  setTimeout(callback, randInt(1000), x * 3);
};
const sub2 = (callback, x) => {
  setTimeout(callback, randInt(1000), x - 2);
};
const split = (callback, x) => {
  setTimeout(callback, randInt(1000), x, x);
};
const add = (callback, x, y) => {
  setTimeout(callback, randInt(1000), x + y);
};
const div4 = (callback, x) => {
  setTimeout(callback, randInt(1000), x / 4);
};

const computation = waterfall(add5, mult3, sub2, split, add, div4);
computation(console.log, 5); // Logs 14

// same as:

const computation2 = (input, callback) => {
  const f6 = (x) => div4(callback, x);
  const f5 = (x, y) => add(f6, x, y);
  const f4 = (x) => split(f5, x);
  const f3 = (x) => sub2(f4, x);
  const f2 = (x) => mult3(f3, x);
  add5(f2, input);
};

reduce 和 reduceRight 之间的区别

js
const a = ["1", "2", "3", "4", "5"];
const left = a.reduce((prev, cur) => prev + cur);
const right = a.reduceRight((prev, cur) => prev + cur);

console.log(left); // "12345"
console.log(right); // "54321"

定义可组合函数

函数组合是一种组合函数的机制,其中每个函数的输出都传递到下一个函数,最后一个函数的输出是最终结果。在此示例中,我们使用 reduceRight() 来实现函数组合。

另请参阅维基百科上的 函数组合

js
const compose =
  (...args) =>
  (value) =>
    args.reduceRight((acc, fn) => fn(acc), value);

// Increment passed number
const inc = (n) => n + 1;

// Doubles the passed value
const double = (n) => n * 2;

// using composition function
console.log(compose(double, inc)(2)); // 6

// using composition function
console.log(compose(inc, double)(2)); // 5

将 reduceRight() 与稀疏数组一起使用

reduceRight() 跳过稀疏数组中的缺失元素,但它不会跳过 undefined 值。

js
console.log([1, 2, , 4].reduceRight((a, b) => a + b)); // 7
console.log([1, 2, undefined, 4].reduceRight((a, b) => a + b)); // NaN

在非数组对象上调用 reduceRight()

reduceRight() 方法读取 thislength 属性,然后访问每个键为小于 length 的非负整数的属性。

js
const arrayLike = {
  length: 3,
  0: 2,
  1: 3,
  2: 4,
  3: 99, // ignored by reduceRight() since length is 3
};
console.log(Array.prototype.reduceRight.call(arrayLike, (x, y) => x - y));
// -1, which is 4 - 3 - 2

规范

规范
ECMAScript 语言规范
# sec-array.prototype.reduceright

浏览器兼容性

BCD 表格仅在启用 JavaScript 的浏览器中加载。

另请参阅