有如下js:
function startTimer(sentence) { alert('start'); sentence.longPressTimer = setTimeout(function() { alert(sentence); //此处sentence为undefined }, 1000); } function endTimer(sentence) { alert('end'); clearTimeout(sentence.longPressTimer); } var sentences = document.querySelectorAll('span.sentence'); alert(sentences.length); for (var i = 0; i < sentences.length; i++) { sentences[i].addEventListener('touchstart', function(){ startTimer(sentences[i]); }); }
经过询问gpt3.5,成功解决了问题。回复如下:
根据你的代码,问题在于 sentences[i]
在回调函数中无法正确地获取到。这是因为回调函数是异步的,当它被调用时,循环已经结束了,此时 i
的值为 sentences.length
,导致无法正确获取到 sentences[i]
。
为了解决这个问题,我们可以使用闭包来创建一个独立的作用域,以便在每次迭代中捕获正确的 sentences[i]
值。可以通过将 sentences[i]
作为参数传递给一个立即执行的函数表达式来实现闭包。修正后的代码如下所示:
function startTimer(sentence) { alert('start'); sentence.longPressTimer = setTimeout(function() { alert(sentence); }, 1000); } function endTimer(sentence) { alert('end'); clearTimeout(sentence.longPressTimer); } var sentences = document.querySelectorAll('span.sentence'); for (var i = 0; i < sentences.length; i++) { (function(index) { sentences[index].addEventListener('touchstart', function() { startTimer(sentences[index]); }); })(i); }
在这个修正后的代码中,我们使用立即执行的函数表达式 (function(index) { ... })(i)
来创建一个闭包。index
参数接收了循环的当前索引值 i
,并在闭包内部被捕获。这样,在每次迭代中,都会创建一个新的独立作用域,并将正确的 sentences[i]
值传递给 startTimer()
函数。