Array.prototype.reduceRight()
reduceRight() 方法用于 Array 实例,它从数组的右侧(从最后一个元素开始)对数组中的每个元素执行一个函数,并将累加器的结果作为下一次迭代的累加器传入,最终将数组归约成一个单一的值。
有关从左到右处理的说明,请参阅 Array.prototype.reduce()。
试一试
const array = [
[0, 1],
[2, 3],
[4, 5],
];
const result = array.reduceRight((accumulator, currentValue) =>
accumulator.concat(currentValue),
);
console.log(result);
// Expected output: Array [4, 5, 2, 3, 0, 1]
语法
reduceRight(callbackFn)
reduceRight(callbackFn, initialValue)
参数
callbackFn-
要对数组中的每个元素执行的回调函数。其返回值会成为下一次调用
callbackFn时accumulator参数的值。对于最后一次调用,其返回值将成为reduceRight()的返回值。该函数会接收以下参数:accumulator-
上一次调用
callbackFn所返回的值。第一次调用时,如果指定了initialValue,则其值为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 没有惰性求值语义,因此 reduce 和 reduceRight 之间没有性能差异。
示例
如何在没有初始值的情况下使用 reduceRight()
对 reduceRight callbackFn 的调用看起来会像这样
arr.reduceRight((accumulator, currentValue, index, array) => {
// …
});
第一次调用函数时,accumulator 和 currentValue 可以是两种值之一。如果在调用 reduceRight 时提供了 initialValue,则 accumulator 将等于 initialValue,而 currentValue 将等于数组中的最后一个值。如果没有提供 initialValue,则 accumulator 将等于数组中的最后一个值,而 currentValue 将等于倒数第二个值。
如果数组为空且未提供 initialValue,则会抛出 TypeError。如果数组只有一个元素(无论位置如何)且未提供 initialValue,或者提供了 initialValue 但数组为空,则将返回该单个值,而不会调用 callbackFn。
函数的一些示例运行流程如下
[0, 1, 2, 3, 4].reduceRight(
(accumulator, currentValue, index, array) => accumulator + currentValue,
);
回调函数将被调用四次,每次调用的参数和返回值如下
accumulator |
currentValue |
index |
返回值 | |
|---|---|---|---|---|
| 第一次调用 | 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()
在这里,我们使用相同的算法来归约同一个数组,但将 10 作为 initialValue 传递给 reduceRight() 的第二个参数。
[0, 1, 2, 3, 4].reduceRight(
(accumulator, currentValue, index, array) => accumulator + currentValue,
10,
);
accumulator |
currentValue |
index |
返回值 | |
|---|---|---|---|---|
| 第一次调用 | 10 |
4 |
4 |
14 |
| 第二次调用 | 14 |
3 |
3 |
17 |
| 第三次调用 | 17 |
2 |
2 |
19 |
| 第四次调用 | 19 |
1 |
1 |
20 |
| 第五次调用 | 20 |
0 |
0 |
20 |
这次 reduceRight 返回的值将是 20。
对数组中的所有值进行求和
const sum = [0, 1, 2, 3].reduceRight((a, b) => a + b);
// sum is 6
按顺序运行一个包含回调函数的异步函数列表,将每个函数的结果传递给下一个函数。
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 mul3 = (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, mul3, 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) => mul3(f3, x);
add5(f2, input);
};
reduce 和 reduceRight 之间的区别
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() 来实现函数组合。
有关函数组合的更多信息,请参阅 Wikipedia 上的函数组合。
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 值。
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() 方法读取 this 的 length 属性,然后访问键是小于 length 的非负整数的每个属性。
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® 2026 语言规范 # sec-array.prototype.reduceright |
浏览器兼容性
加载中…