当我在一个嵌套的for循环中使用splice时,我遇到了一个我无法理解的行为。
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()之后调用splice……那么它之前是如何拼接的呢?
发布于 2013-02-16 22:32:18
为什么索引2引用值3,而它应该引用2
因为在上一次迭代中,您通过splice删除了一个条目
if (c==="1")
a.splice(c, 1);...so一切都向上移动(这就是splice所做的)。然后,下一个循环继续,c为"2",索引2处的条目(现在)为3。
请回复您的评论:
splice ok,我知道它会在拼接后移动索引,但我在执行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 (不是a,因为a已更改),因此您的日志语句显示为"2"稍后,当您的外部循环再次运行时,c在某一时刻再次为"1",因此删除另一个条目,您将看到相同的效果。
您应该做的是实际观看代码运行,使用调试器单步执行,并实时观察a是如何变化的。所有现代浏览器都内置了强大的调试器,您不必在代码中使用console.log语句,您可以实际观察发生了什么。
这不是问题的原因,但请注意,for-in不是用来循环数组索引的,它是用来枚举对象的属性名的(这就是c==="1"比较有效的原因,属性名始终是字符串)。更多信息:
发布于 2013-02-16 22:32:40
删除元素1之后,"a“看起来像这样:
[0, 2, 3, 4]新的元素1是2。循环的下一次迭代,那么"c“是2,a[2]确实是3。
发布于 2013-02-16 22:35:32
你应该使用not use for…in-enumerations to loop arrays。
这就是说,你的问题是.splice method修改了你的数组,移除了一个项目,并在它之后调整了indizes。然而,你没有调整你的迭代变量,所以它将跳过索引-旧的索引"1“已经被访问了,下一个将是"2”而不是新的"1“。
要解决此问题,您可以向后循环,或者将迭代计数器减少该数量或删除的项。但是,当重新访问索引时,您的条件将始终得到满足,并且您将从数组中连续删除所有第二个元素,直到没有第二个元素-不确定这是否是您的目标。
https://stackoverflow.com/questions/14911312
复制相似问题