.innerHTML与setTimeout一起在循环中仅打印最后一部分。
在上述代码中,通过循环遍历数组`words`,使用`setTimeout`函数来延迟执行一段代码。在每次循环中,将`words`数组中的元素分别添加到HTML页面中的两个元素的`innerHTML`属性中。
然而,当代码执行时,只有最后一个元素"word4"被正确地添加到HTML页面中。原因是在每次`setTimeout`函数执行时,`i`的值已经达到了`words`数组的长度,因此在`words[i]`中获取到的是`undefined`。
这是由于`setTimeout`函数是异步执行的,在循环过程中,`setTimeout`函数被触发的时间是在循环结束之后。因此,在`setTimeout`函数执行时,循环已经结束,`i`的值已经变成了`words`数组的长度。
为了解决这个问题,可以使用闭包来创建一个新的作用域,在每次迭代中将`i`的值保存下来。可以通过将`setTimeout`函数的参数包裹在一个立即执行的匿名函数中来实现这一点。
修改后的代码如下所示:
const words = ["Word1", "word2", "word3", "word4"]; for (let i = 0; i < words.length; i++) { console.log(words[i]); (function(i) { setTimeout(function() { document.getElementById('test').innerHTML += words[i]; document.getElementById('test2').innerHTML = words[i]; }, 2000 * i); })(i); }
通过将代码包装在立即执行的匿名函数中,每次循环迭代时,都会创建一个新的作用域,并将当前的`i`值作为参数传递给该函数。这样,每个`setTimeout`函数在执行时,都会使用正确的`i`值来获取数组中的元素,并将其添加到HTML页面中。
这样修改后的代码将按照预期的方式,依次将"Word1"、"word2"、"word3"和"word4"添加到HTML页面中的两个元素中。