面试题答案
一键面试使用闭包解决问题的代码示例
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
都是当时传入的对应循环索引值,从而保证了输出结果符合预期。