我正在同splice
内嵌套的for循环和我碰到一个行为我无法理解来了。
var a = [0, 1, 2, 3, 4];
for (b in a) {
console.log(a);
for (c in a) {
console.log(c + '==' + a[c]);
if (c === "1")
a.splice(c, 1);
}
}
console.log(a);
它的输出是奇怪
[0, 1, 2, 3, 4]
"0==0"
"1==1"
"2==3" // why is index 2 referring to value 3 , whereas it should refer to 2
"3==4"
[0, 2, 3, 4]
"0==0"
"1==2"
"2==4" // index 2 referring to value 4 , whereas it should refer to 3
[0, 3, 4]
"0==0"
"1==3"
[0, 4]
我拼接指标1,它是跳过下一个元素。
为什么这种行为...
这里结帐: http://jsbin.com/isahoj/3/edit
编辑:
好吧,我明白,它拼接后转移的索引,但我打电话做的console.log()后,拼接......所以它是如何更早拼接?
为什么索引2参照值3,而它应该是指2
因为以前迭代上,已卸下通过入口splice
:
if (c==="1")
a.splice(c, 1);
......所以一切都向上移动(这是splice
一样)。 然后下一个循环继续c
为"2"
,并且在索引2的条目(现在)为3
。
回复您的评论:
好吧,我明白,它拼接后转移的索引,但我打电话做的console.log()后,拼接......所以它是如何更早拼接?
好吧,让我们退后一步:
内循环开始前, a
看起来是这样的:
[0, 1, 2, 3, 4]
在你的内循环的第一遍, c
是"0"
,并在索引条目0
是0
,所以你的日志语句显示"0==0"
。 splice
不叫,和a
没有改变,所以它仍然是这样的:
[0, 1, 2, 3, 4]
在你的内循环的下传, c
是"1"
,并在索引条目1
为1
,那么您的日志语句显示"1==1"
。 然后splice
叫 ,改变a
所以它看起来是这样的:
[0, 2, 3, 4]
在你的内循环的下传, c
是"2"
,并在索引条目2
是3
(不是2
,因为a
已经改变),所以你的日志语句显示"2==3"
。
后来,当你的外环再次运行, c
又是"1"
在一个点上,所以另一个条目被删除,你会看到同样的效果。
你应该做的实际上是看代码的运行实况,单步通过与调试,以及如何看a
实时变化。 所有现代浏览器都内置了能调试器,你不必用垃圾代码console.log
语句,实际上你可以看看会发生什么。
这不是你的问题的原因,但要注意for-in
不是遍历数组索引,它是枚举对象的属性名称(这就是为什么你c==="1"
相比作品,属性名称总是字符串)。 更多: 神话与现实的for..in
在删除元素1,然后“一”的样子:
[0, 2, 3, 4]
新的元件1是2循环的下一次迭代,则“c”是2,和a[2]
确实是3。
您应不使用for…in
-enumerations循环数组 。
这就是说,你的问题是.splice
方法修改你的阵列,删除一个项目,后调整indizes。 然而,你不调整你的迭代变量,所以它会跳过指数 - 旧索引“1”已经被参观了,接下来将是“2”,而不是新的“1”一次。
为了解决这个问题,你可以循环向后或减少的数量或删除的项目迭代计数器。 然而,重新审视该指数当你的条件总是满足,与你依次去除阵列的所有第二部件,直到有没有留下第二个元素 - 不知道这是否是你的目标。