JavaScript的接续跳元素 - 为什么这种行为(javascript splice skipp

2019-08-17 00:12发布

我正在同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()后,拼接......所以它是如何更早拼接?

Answer 1:

为什么索引2参照值3,而它应该是指2

因为以前迭代上,已卸下通过入口splice

if (c==="1")
    a.splice(c, 1);

......所以一切都向上移动(这是splice一样)。 然后下一个循环继续c"2" ,并且在索引2的条目(现在)为3


回复您的评论:

好吧,我明白,它拼接后转移的索引,但我打电话做的console.log()后,拼接......所以它是如何更早拼接?

好吧,让我们退后一步:

  1. 内循环开始前, a看起来是这样的:

     [0, 1, 2, 3, 4] 
  2. 在你的内循环的第一遍, c"0" ,并在索引条目00 ,所以你的日志语句显示"0==0"splice 叫,和a没有改变,所以它仍然是这样的:

     [0, 1, 2, 3, 4] 
  3. 在你的内循环的下传, c"1" ,并在索引条目11 ,那么您的日志语句显示"1==1" 。 然后splice ,改变a所以它看起来是这样的:

     [0, 2, 3, 4] 
  4. 在你的内循环的下传, c"2" ,并在索引条目23 (不是2 ,因为a已经改变),所以你的日志语句显示"2==3"

后来,当你的外环再次运行, c又是"1"在一个点上,所以另一个条目被删除,你会看到同样的效果。

你应该做的实际上是看代码的运行实况,单步通过与调试,以及如何看a实时变化。 所有现代浏览器都内置了能调试器,你不必用垃圾代码console.log语句,实际上你可以看看会发生什么。


这不是你的问题的原因,但要注意for-in不是遍历数组索引,它是枚举对象的属性名称(这就是为什么你c==="1"相比作品,属性名称总是字符串)。 更多: 神话与现实的for..in



Answer 2:

在删除元素1,然后“一”的样子:

[0, 2, 3, 4]

新的元件1是2循环的下一次迭代,则“c”是2,和a[2]确实是3。



Answer 3:

您应不使用for…in -enumerations循环数组 。

这就是说,你的问题是.splice方法修改你的阵列,删除一个项目,后调整indizes。 然而,你不调整你的迭代变量,所以它会跳过指数 - 旧索引“1”已经被参观了,接下来将是“2”,而不是新的“1”一次。

为了解决这个问题,你可以循环向后或减少的数量或删除的项目迭代计数器。 然而,重新审视该指数当你的条件总是满足,与你依次去除阵列的所有第二部件,直到有没有留下第二个元素 - 不知道这是否是你的目标。



文章来源: javascript splice skipping element- why this behaviour