Javascript array.forEach(function) 执行函数的次数是预期的两倍

Javascript array.forEach(function) executing function twice as many times as expected

我有一个 html 文件,上面只有一个按钮

<!DOCTYPE html>
<html>    <body>
<p>Click the button to list all the items in the array.</p>

<button onclick = "numbers.forEach(myFunction)" >Try it</button>

<p id="demo"></p>
</body>     
</html>

我还有 Javascript 文件,其中包含 .forEach 方法的 onclick 函数。
单击按钮时,我想遍历一个数组,循环遍历数组中的每个元素实例。

对于这个数组中的每个元素,我想用一个计时器打印出它的索引和值,然后等待一秒钟以显示下一个排列。

demoP = document.getElementById("demo");
var numbers = [];

var random = Math.floor(Math.random() * 4) + 1;

numbers.push(random);

function myFunction(item, index) {
  random = Math.floor(Math.random() * 4) + 1;
  numbers.push(random);
  demoP.innerHTML = demoP.innerHTML + "numbers[" + index + "]: " + item + "<br>"; 
  //demoP.innerHTML = demoP.innerHTML + "<br>" //add magic spacing between permutation
  sleep(100);
  //switch to this and see how slow?
  //sleep(1000);
}

function sleep(milliseconds) {
  var start = new Date().getTime();
  for (var i = 0; i < 1e7; i++) {
    if ((new Date().getTime() - start) > milliseconds){
      break;
    }
  }
}

我希望用户点击按钮时显示的结果是:

numbers[0] = 4
//waits a second and adds a <br> here to separate
numbers[0] = 4
numbers[1] = 2
//waits a second and adds a <br> here
numbers[0] = 4
numbers[1] = 2
numbers[2] = 3

等等。

目前代码输出的元素数量至少是原来的两倍,而且 sleep() 的持续时间似乎比应有的长。

除了可怕的 sleep 功能。您正在使用 myFunction 作为 forEach 的回调,并且在 myFunction 中,您正在将新元素推送到 numbers,这与您调用 forEach 的数组相同上。

forEach 不会在仍然循环数组的同时对新推送的项目调用回调。但是到循环结束时,数组中的项目将加倍。根据 MDN:

The range of elements processed by forEach() is set before the first invocation of callback. Elements that are appended to the array after the call to forEach() begins will not be visited by callback.

如果数组包含N个元素,那么当点击发生时,会显示N个元素,并且myFunction会压入N个其他元素,当下一次点击发生 2N 元素这次将显示,...

所以每次点击之后,数组中的元素都会翻倍。