js 闭包使用一例

有如下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() 函数。

posted on 2023-11-27 15:27  空明流光  阅读(1)  评论(0编辑  收藏  举报

导航