【问题标题】:Explaination needed: Different outputs when used for...in and for(;;) in JavaScript需要解释:在 JavaScript 中使用 for...in 和 for(;;) 时输出不同
【发布时间】:2015-02-11 01:19:43
【问题描述】:

在 NodeJS 中,我创建了以下两个脚本,它们都旨在从数组中删除偶数。

这是我的第一个脚本:

#!/usr/bin/nodejs
var myarr = [2,3,5,1,6,2,28,5,7,90,3];
console.log(myarr);
for(var i in myarr){
        if(myarr[i] % 2 == 0){
                myarr.splice(i,1);
                --i;
        }
}
console.log(myarr);

第一个脚本的输出如下:

[ 2, 3, 5, 1, 6, 2, 28, 5, 7, 90, 3 ]
[ 3, 5, 1, 2, 5, 7, 3 ]

在第二个脚本中,我将for..in 循环更改为for(;;) 循环,如下所示:

#!/usr/bin/nodejs
var myarr = [2,3,5,1,6,2,28,5,7,90,3];
console.log(myarr);
for(var i=0;i<myarr.length;i++){
        if(myarr[i] % 2 == 0){
                myarr.splice(i,1);
                --i;
        }
}
console.log(myarr);

我得到了第二个脚本的以下输出:

[ 2, 3, 5, 1, 6, 2, 28, 5, 7, 90, 3 ]
[ 3, 5, 1, 5, 7, 3 ]

虽然我的意图是相同的,但两个 for 循环给了我不同的输出。我发现,在我的第一个脚本中,如果原始数组中存在两个相邻的偶数,if 条件似乎仅适用于第一个偶数,只有在第二个偶数被跳过的情况下。如果有人能清楚地解释这种差异,我将不胜感激。

【问题讨论】:

  • 不要使用for...in 遍历数组(或一般的集合)。
  • 同时迭代和删除不是一个好主意。
  • 为了更好地了解正在发生的事情,请将 console.log('i = ' , i, ' myarr = ', myarr); 放在 for(var i in myarr){ 之后。
  • es5.github.io/#x12.6.4: "在任何枚举中不能多次访问属性名称。"。 for in 循环中的 --i 是徒劳的(但是,您可以使用 while 而不是 if)。

标签: javascript node.js for-loop for-in-loop


【解决方案1】:

你做错了。您正在从数组中删除键,同时循环遍历同一个数组。您的 for...in 循环只会执行 7 次迭代,因为您的 4 个键是从数组拼接的,而数组仍在迭代,而您的 for(;;) 循环将始终执行所有 11 次迭代,因为这是在开头定义的(myarr.length)。

你应该定义第二个数组来代替你的结果:

为了……在

var myarr = [2,3,5,1,6,2,28,5,7,90,3],
    resultarr = [];
console.log(myarr);
for(var i in myarr){
    if(myarr[i] % 2 != 0){
        resultarr.push(myarr[i])
    }
}
console.log(resultarr);
-> [3, 5, 1, 5, 7, 3]

for(;;)

var myarr = [2,3,5,1,6,2,28,5,7,90,3],
    resultarr = [];
console.log(myarr);
for(var i=0;i<myarr.length;i++){
    if(myarr[i] % 2 != 0){
        resultarr.push(myarr[i]);
    }
}
console.log(resultarr);
-> [3, 5, 1, 5, 7, 3]

作为结束说明,无论如何您都不应该使用for...in 循环来遍历数组。 This answer 详细说明了为什么这是一个坏主意。

【讨论】:

  • 非常感谢您的解释。我知道我可以使用第二个数组来推送奇数。但我想在不使用任何额外数组的情况下做到这一点。
猜你喜欢
  • 2022-01-12
  • 2013-08-31
  • 1970-01-01
  • 1970-01-01
  • 2010-09-19
  • 2016-03-30
相关资源
最近更新 更多