MST

星途 面试题库

面试题:JavaScript闭包在复杂定时器场景中的应用

假设有一个循环创建多个`setTimeout`定时器的场景,每个定时器需要输出当前循环的索引值。请使用闭包解决这个问题,并解释为什么不使用闭包会导致输出结果不符合预期,以及闭包在这里是如何保持每个索引值的正确状态的。
22.7万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试

使用闭包解决问题的代码示例

for (var i = 0; i < 5; i++) {
    (function (index) {
        setTimeout(function () {
            console.log(index);
        }, 1000 * index);
    })(i);
}

不使用闭包导致结果不符合预期的原因

在JavaScript中,setTimeout中的回调函数是异步执行的。如果不使用闭包,直接在setTimeout中访问循环变量i,当定时器触发回调函数时,循环早已结束,i的值已经变成了循环结束后的最终值(在上述例子中,i最终为5)。所以每个定时器输出的都是5,而不是期望的当前循环的索引值。

闭包保持每个索引值正确状态的原理

上述代码中,通过立即执行函数表达式(IIFE)创建了闭包。每次循环时,(function (index) { ... })(i) 这个IIFE会立即执行,将当前的 i 值作为参数 index 传递进去。这个 index 变量在IIFE内部有自己独立的作用域,它的值会被闭包保存下来。所以每个定时器回调函数中访问的 index 都是当时传入的对应循环索引值,从而保证了输出结果符合预期。