JavaScript setTimeout 与闭包陷阱:变量共享问题解析

作者:异步漫步时间:2026-10-28 14:19:31浏览:257

本文探讨 JavaScript 中 setTimeout 结合闭包时的常见陷阱。通过循环内使用 setTimeout 打印变量的示例,解释为何输出结果与预期不符,并展示如何利用立即执行函数(IIFE)创建独立作用域来保存循环变量值,从而正确获取每个迭代的状态。

setTimeout 基础用法

setTimeout 常用于延迟执行特定函数,其基本语法结构如下:

代码如下:

setTimeout(function(){
…
}, timeout);

为了实现异步处理,开发者有时会使用 setTimeout 并将延迟时间设为 0,例如:

代码如下:

function f(){
… // get ready
setTimeout(function(){
…. // do something
}, 0);
  
return …;
}

在 setTimeout 指定的回调函数执行之前,函数 f 就已经返回了。

在进行异步处理,特别是涉及闭包特性时,需要格外谨慎。

例如:

代码如下:

闭包陷阱与变量共享问题for(var i = 0 ; i < 10; i++){
setTimeout(function(){
console.log(i);
}, 0);
}

对于初次尝试这种方式的用户,可能会预期程序会依次打印 0 到 9,但实际结果却是打印了 10 次 10。原因在于,当循环结束时,回调函数才真正执行,此时变量 i 的值已经变为 10,因此 console.log(i) 输出的是 10。如果你的目标是打印 0 到 9,可以换一种方式,通过函数参数来保存 0 到 9 的值(这同样利用了闭包特性):

代码如下:

利用闭包保存循环变量for(var i = 0 ; i < 10; i++){
setTimeout((function(i){
return function(){
console.log(i);
}
})(i), 0);
}
作者最新文章