修改forEach中的数组

时间:2014-11-30 11:43:29

标签: javascript arrays foreach

我需要在Array.forEach的中间插入一些数组。我想检查JavaScript如何处理这些情况。我期待任何事情,包括无尽的循环。但结果对我来说很奇怪。你能解释一下这里发生了什么:



var A = [0, 1, 2, 3, 4, 5, 6, 7]
A.forEach(function(x) {
   if (x == 3) A.splice(1, 0, 'new')
})
document.write(JSON.stringify(A))




3 个答案:

答案 0 :(得分:3)

观察大量中间writeln s:

  1. forEach循环只查看每个原始索引一次 - 因此它必须将数组的长度存储在某个临时变量中。

  2. splice行在同一位置插入“new”:在第一个元素之后。

  3. 只有在第4位看到“3”后才会发生这种情况。

  4. 所以在第3次迭代中,在第一次插入之后,你的数组看起来像这样:

    [ 0, "new", 1, 2, 3, 4, 5, 6, 7 ]
    

    并且forEach迭代器位于元素4 - 再次是“3”。

  5. ..因此,原始数组长度的剩余部分会插入“new”。

  6. forEach循环代码的编写者必须考虑有人在幕后更改数组。一个稍微更安全的方法可能是制作原始数组的副本,但我认为这需要一个副本(你事先不能知道这个变化有多深),这可能导致大量复制似乎是一个边缘案例。

答案 1 :(得分:3)

你得到的是预期的行为,虽然它不是一个真正的无限循环 - 它是一个非生产性的循环。

您正在当前索引之前添加元素。这使当前值移动,因此您将在每次迭代时开始获得x == 3。

这是无限循环的所有前提,但是JS forEach为它设置了一个上限,并且该上限是原始数组中存在的元素数量。无论你如何操纵数组,它都不能运行超过8次,这是原始长度。

此代码的输出显示了最佳情况:

  var A = [0, 1, 2, 3, 4, 5, 6, 7]
  A.forEach(function(x, index) {
    document.writeln('A[' + index + '] = ' + x + '<br/>');
    if (x == 3) {
      A.splice(1, 0, 'new')
    }
  })
  document.write(JSON.stringify(A));

输出:

A[0] = 0
A[1] = 1
A[2] = 2
A[3] = 3
A[4] = 3
A[5] = 3
A[6] = 3
A[7] = 3
[0,"new","new","new","new","new",1,2,3,4,5,6,7]

答案 2 :(得分:1)

好的,让我们按步骤进行:

  1. 你的循环正常迭代,直到元素&#34; 3&#34;

  2. 关于元素&#34; 3&#34;你的循环过去&#34;新&#34;在数组的第一个位置,如: [0,new,1,2,3,4,5,6,7],但是你的所有元素都在一个位置向右移动,所以在循环的第四个元素的下一次迭代中再次#34; 3& #34;因为它被移动了。

  3. 他重复步骤2直到最后的第8个元素,并且重复4次以及#34; new&#34;在阵列的第一个位置。 如果你想粘贴&#34; new&#34;有一次这样做:

    A.forEach(function(x){
       if(x == 3){A.splice(1,0,&#39; new&#39;);打破;} })