使用 Array 对象方法可以修改 Array 内容,但与基本的 for 循环相比,这些方法缺少一项重要功能。运行时不能修改索引。
例如,如果您将删除当前元素并将其放置到同一数组中的另一个索引位置,您可以轻松地做到这一点。如果您将当前元素移动到之前的位置,那么在下一次迭代中您将获得相同的下一项,就好像您什么都没做一样。
考虑一下这段代码,一旦索引计数达到 5,我们将索引位置 5 处的项目移动到索引位置 2。
var ar = [0,1,2,3,4,5,6,7,8,9];
ar.forEach((e,i,a) => {
i == 5 && a.splice(2,0,a.splice(i,1)[0])
console.log(i,e);
}); // 0 0 - 1 1 - 2 2 - 3 3 - 4 4 - 5 5 - 6 6 - 7 7 - 8 8 - 9 9
但是,如果我们将当前元素移动到当前索引位置之外的某个位置,事情就会变得有些混乱。然后下一个项目将移动到已移动项目的位置,在下一次迭代中我们将无法看到或评估它。
考虑一下这段代码,一旦索引计数达到 5,我们将索引位置 5 处的项目移动到索引位置 7。
var a = [0,1,2,3,4,5,6,7,8,9];
a.forEach((e,i,a) => {
i == 5 && a.splice(7,0,a.splice(i,1)[0])
console.log(i,e);
}); // 0 0 - 1 1 - 2 2 - 3 3 - 4 4 - 5 5 - 6 7 - 7 5 - 8 8 - 9 9
所以我们从未在循环中遇到过 6。通常在 for 循环中,当您将数组项向前移动时,您应该减少索引值,以便您的索引在下一次运行中保持在相同的位置,并且您仍然可以评估移动到已删除项的位置的项。这对于数组方法是不可能的。您不能更改索引。检查以下代码
var a = [0,1,2,3,4,5,6,7,8,9];
a.forEach((e,i,a) => {
i == 5 && (a.splice(7,0,a.splice(i,1)[0]), i--);
console.log(i,e);
}); // 0 0 - 1 1 - 2 2 - 3 3 - 4 4 - 4 5 - 6 7 - 7 5 - 8 8 - 9 9
正如你所见,当我们减少 i 时,它不会从 5 继续,而是从 6 开始。
所以请记住这一点。