Javascript中的ForEach跳过条目

ForEach in Javascript skipping entries?

本文关键字:中的 ForEach Javascript      更新时间:2023-09-26

我正在检查一组文本条目,看看它们是否符合邮政编码格式。这是我的代码:

var invZIPs;
ZIP.forEach(function(z, i) {
    console.log(z);
    console.log(ZIP);
    if(!isZIP(z)){
        invZIPs += "(" + z + ")";
        ZIP.splice(i,1);
    }
    console.log(ZIP);
});
if(invZIPs != ""){
    console.log(""Ignored unrecognized entries: " + invZIPs");
}

为了调试,我在检查之前和之后打印forEach条目和数组。这是我的输出。

1
["1", "2", "31833", "4", "5"]
["2", "31833", "4", "5"]
31833
["2", "31833", "4", "5"]
["2", "31833", "4", "5"]
4
["2", "31833", "4", "5"]
["2", "31833", "5"]

为什么它不检查某些条目?

为什么它不检查某些条目?

将被访问的元素的范围是在回调循环开始之前确定的,并且即使删除了正在访问的条目,也会继续下一个循环。(请参见规范)因此,如果在迭代过程中修改数组,将会得到奇怪的效果。例如,假设条目0无效;您删除它,使条目1条目0、条目2条目1等。;则循环以条目CCD_ 6继续并且从不检查(新的)条目0

在这种情况下Array#filter可能是更好的选择。

ZIP = ZIP.filter(function(z, i) {   // Note we're assigning the new array
    console.log(z);
    console.log(ZIP);
    if(!isZIP(z)){
        invZIPs += "(" + z + ")";
        return false;               // Leave it out of the result
    }
    console.log(ZIP);
    return true;                    // Include it in the result
});

旁注:您也永远不会给invZIPs一个初始值。从你对+=的使用来看,你可能想要

var invZIPs = "";

要回答这个问题,第一次通过循环时,将测试索引为0的成员,并将其从数组中拼接出来,因此所有成员都将向下移动一个。

在下一次迭代中,将测试索引为1的成员。由于上一个循环进行了拼接并向下移动了所有内容,索引1处的成员就是最初位于索引2处的成员,依此类推。因此,每次拼接成员时,都会跳过下一个成员。

解决方案是从结束处迭代,而不是从开始处迭代,因此拼接不会造成这种影响。