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

Javascript forEach(函数)执行函数的次数是预期的两倍,javascript,arrays,foreach,sleep,Javascript,Arrays,Foreach,Sleep,我有一个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>

我有一个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>
当用户单击按钮时,我希望显示的结果是:

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
数字[0]=4
//等待一秒钟,并在此处添加一个
来分隔 数字[0]=4 数字[1]=2 //等待一秒钟并在此处添加一个
数字[0]=4 数字[1]=2 数字[2]=3
等等


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

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

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

forEach()
处理的元素范围在第一次调用
回调之前设置。调用
forEach()
开始后附加到数组的元素将不会被
回调访问

如果数组包含
N
元素,则当单击发生时,将显示
N
元素,
myFunction
将推送
N
其他元素,当下次单击发生时,此时将显示
2N
元素


因此,在每次单击之后,数组中的元素将加倍。

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

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

forEach()
处理的元素范围在第一次调用
回调之前设置。调用
forEach()
开始后附加到数组的元素将不会被
回调访问

如果数组包含
N
元素,则当单击发生时,将显示
N
元素,
myFunction
将推送
N
其他元素,当下次单击发生时,此时将显示
2N
元素


因此,每次单击后,数组中的元素都将加倍。

请不要尝试添加
睡眠功能。相反,学习如何通过
setTimeout
setInterval
之类的方法进行asyc调用。也可以考虑使用<代码>控制台。log < /Cord>跟踪代码。而且,由于您在执行
forEach
操作时更改了数组
编号
,因此您在询问问题。在DOM元素
onclick
属性中执行
forEach
并不是最好的方法。让
onclick
调用一个函数,并在该函数中执行
forEach
。@Intervalia我对它的插入次数有问题,所以我没有使用“setTimeout”或“setInterval”,而是创建了一个“sleep()”来测试它。@Jamin我在回答中犯了一个错误。请阅读新的更新版本。很抱歉请不要尝试添加
睡眠
功能。相反,学习如何通过
setTimeout
setInterval
之类的方法进行asyc调用。也可以考虑使用<代码>控制台。log < /Cord>跟踪代码。而且,由于您在执行
forEach
操作时更改了数组
编号
,因此您在询问问题。在DOM元素
onclick
属性中执行
forEach
并不是最好的方法。让
onclick
调用一个函数,并在该函数中执行
forEach
。@Intervalia我对它的插入次数有问题,所以我没有使用“setTimeout”或“setInterval”,而是创建了一个“sleep()”来测试它。@Jamin我在回答中犯了一个错误。请阅读新的更新版本。很抱歉
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