假设我有一个数组:
const ar = [1,2,3,4];
我将reduce函数应用于它,在该函数内部我删除了这样的元素:
ar.reduce((result, element, index, original)=>{
original.pop();
}, []);
对于前两个元素,该函数仅执行两次。这是可以理解的,因为我在之前的电话中删除了第3和第4个元素。
但有趣的是,如果我执行该函数并删除当前元素:
ar.reduce((result, element, index, original)=>{
original.splice(index, 1);
}, []);
对于前两个元素,该函数仍然执行两次。为什么不对3rd
和4th
元素执行它们,因为它们保留在数组中?
这种行为是否记录在任何地方?在一个规格可能吗?
答案 0 :(得分:3)
在你的第二个例子中,它实际上是为 1st 和 3rd 元素执行的,而不是前两个元素:
const ar = [1, 2, 3, 4];
ar.reduce((result, element, index, original)=>{
console.log(element, index);
original.splice(index, 1);
}, []);
console.log(ar);

1 2 3 4
^
此处,虽然reduce element
为1
且index
为0
,但它会调用splice
,删除第一个元素,然后迭代到下一个索引:
2 3 4
^
此处,简化element
为3
,index
为1
。删除后,index
将等于ar.length
,它会停止,并留下
2 4
reduceRight()
仍将访问所有元素的原因是因为您向后迭代,并且前一个元素位置不受在当前索引处拼接元素的影响:
const ar = [1, 2, 3, 4];
ar.reduceRight((result, element, index, original)=>{
console.log(element, index);
original.splice(index, 1);
}, []);
console.log(ar);

演练:
element = 4, index = 3
1 2 3 4
^
element = 3, index = 2
1 2 3
^
element = 2, index = 1
1 2
^
element = 1, index = 0
1
^
要回答您的问题,请{是ECMAScript documents this behavior for Array#reduce()
as part of the specification:
reduce
处理的元素范围是在第一次调用callbackfn
之前设置的。reduce
将不会访问在callbackfn
调用开始后附加到数组的元素。如果更改了数组的现有元素,则传递给callbackfn
的值将是reduce访问它们时的值; 1}}开始之后和访问之前删除的元素不会被访问。
与上述完全相同的段落也适用于reduce
。
以下是reduceRight
的填充物,遵循规范中的步骤:
Array#reduce()