javascript拼接跳过元素-为什么出现此行为

kar*_*boy -1 javascript splice

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);
Run Code Online (Sandbox Code Playgroud)

它的输出很奇怪

    [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]
Run Code Online (Sandbox Code Playgroud)

我正在拼接索引1,它正在跳过下一个元素。

为什么这种行为...

在这里结帐:http : //jsbin.com/isahoj/3/edit

编辑:
好的,我知道它在拼接后会移动索引,但是我在做console.log()之后调用了拼接...所以它如何在更早的时候拼接?

T.J*_*der 5

为什么索引2引用值3,而索引2引用值2

因为在上一次迭代中,您通过删除了一个条目splice

if (c==="1")
    a.splice(c, 1);
Run Code Online (Sandbox Code Playgroud)

...所以一切都变了(就是splice这样)。然后,下一个循环继续c"2",索引2处的条目(现在)为3


发表您的评论:

好的,我知道它在拼接后会移动索引,但是我在做console.log()之后调用了拼接...那么它如何在更早的时候拼接?

好吧,让我们退后一步:

  1. 在内部循环开始之前,a如下所示:

    [0, 1, 2, 3, 4]
    
    Run Code Online (Sandbox Code Playgroud)
  2. 在内部循环的第一遍,c"0",索引0处的条目是0,因此您的log语句显示为"0==0"splice不是叫,并a没有改变,所以它仍然是这样的:

    [0, 1, 2, 3, 4]
    
    Run Code Online (Sandbox Code Playgroud)
  3. 在您的内部循环的下一遍,c"1",索引1处的条目是1,因此您的log语句显示为"1==1"。然后splice 调用,进行更改a,使其看起来像这样:

    [0, 2, 3, 4]
    
    Run Code Online (Sandbox Code Playgroud)
  4. 在您的内部循环的下一遍,c"2",索引2处的条目是3(不是2,因为a已更改),因此您的log语句显示为"2==3"

稍后,当您的外循环再次运行时,c"1"在某个点,因此删除另一个条目,您会看到相同的效果。

实际上,您应该做的是观察代码的实时运行,调试器的单步调试以及a实时的更改。所有现代的浏览器都内置有功能强大的调试器,您不必用console.log语句来填充代码,您实际上可以观察到会发生什么。


这不是造成问题的原因,但是请注意,这for-in并不是循环数组索引,而是枚举对象的属性名称(这就是为什么您的c==="1"比较有效,属性名称始终为字符串)。更多:神话与现实for..in