for循环 + setTimeout 结合一些示例(前端面试题)

发布时间 - 2026-01-11 03:02:08    点击率:

一、背景

最近在翻看以前的老书《node.js开发指南》,恰好碰到 for 循环 + setTimeout 的经典例子,于是重新梳理了思路并记录下。

二、写在前面,setTimeout 和 setInterval 的执行机制

在日常编码中,你会发现,给 setTimeout 和 setInterval 设定延迟时间往往并不准,或者干脆 setTimeout(function(){xxx},0) 也不是立马执行(特别是有耗时代码在前),这是因为 js 是单线程的,有一个事件队列机制,setTimeout 和 setInterval 的回调会到了延迟时间塞入事件队列中,排队执行。

setTimeout :延时 delay 毫秒之后,啥也不管,直接将回调函数加入事件队列。

setInterval :延时 delay 毫秒之后,先看看事件队列中是否存在还没有执行的回调函数( setInterval 的回调函数),如果存在,就不要再往事件队列里加入回调函数了。

看下面示例:

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

结果:1 秒之后,同时输出 5 个 5。

因为 for 循环会先执行完(同步优先于异步优先于回调),这时五个 setTimeout 的回调全部塞入了事件队列中,然后 1 秒后一起执行了。

三、正文

接下来就是那道经典的代码:

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

结果:5 5 5 5 5

为什么不是 1 2 3 4 5,问题出在作用域上。

因为 setTimeout 的 console.log(i); 的i是 var 定义的,所以是函数级的作用域,不属于 for 循环体,属于 global。等到 for 循环结束,i 已经等于 5 了,这个时候再执行 setTimeout 的五个回调函数(参考上面对事件机制的阐述),里面的 console.log(i); 的 i 去向上找作用域,只能找到 global下 的 i,即 5。所以输出都是 5。

解决办法:人为给 console.log(i); 创造作用域,保存i的值。

解决办法一

for (var i = 0; i < 5; i++) { 
  (function(i){   //立刻执行函数
    setTimeout(function (){
      console.log(i); 
     },1000); 
  })(i); 
}

这里用到立刻执行函数。这样 console.log(i); 中的i就保存在每一次循环生成的立刻执行函数中的作用域里了。

解决办法二

for (let i = 0; i < 5; i++) {   //let 代替 var
  setTimeout(function (){
    console.log(i); 
   },1000); 
}

let 为代码块的作用域,所以每一次 for 循环,console.log(i); 都引用到 for 代码块作用域下的i,因为这样被引用,所以 for 循环结束后,这些作用域在 setTimeout 未执行前都不会被释放。

四、补充

在写示例代码的过程中,发现一个语法点:

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

报错:

TypeError: "callback" argument must be a function
at setTimeout (timers.js:421:11)
……

百度了下,原来 setTimeout 不支持传带参数的函数,可以再用一个匿名函数包装下它吧,见下面代码:

function a(i){ 
  console.log(i);  
}
for (var i = 0; i < 5; i++) { 
  setTimeout(function(){ //用匿名函数包装
    a(i);
  },1000); 
} 

总结

以上所述是小编给大家介绍的for循环 + setTimeout 结合一些示例(前端面试题),希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!


# for  # 循环与settimeout  # js前端面试题及答案整理(一)  # 整理一些最近经常遇到的前端面试题  # 前端面试知识点锦集(JavaScript篇)  # js前端面试之同步与异步问题详解  # 常见前端面试题及答案  # 一次围绕setTimeout的前端面试经验分享  # 前端面试题及答案整理(二)  # 「中高级前端面试」JavaScript手写代码无敌秘籍(推荐)  # 收集前端面试题之url、href、src  # 前端面试知识点目录一览  # Vue面试题及Vue知识点整理  # 关于vue面试题汇总  # 2019年度web前端面试题总结(主要为Vue面试题)  # 回调  # 解决办法  # 小编  # 都是  # 延迟时间  # 还没有  # 是有  # 在此  # 给大家  # 这个时候  # 不支持  # 再用  # 报错  # 不属于  # 在前  # 这是因为  # 你会发现  # 所述  # 里了  # 给我留言 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: zabbix利用python脚本发送报警邮件的方法  Laravel如何正确地在控制器和模型之间分配逻辑_Laravel代码职责分离与架构建议  html5源代码发行怎么设置权限_访问权限控制方法与实践【指南】  如何快速选择适合个人网站的云服务器配置?  在centOS 7安装mysql 5.7的详细教程  消息称 OpenAI 正研发的神秘硬件设备或为智能笔,富士康代工  轻松掌握MySQL函数中的last_insert_id()  如何续费美橙建站之星域名及服务?  详解Android中Activity的四大启动模式实验简述  如何在Windows 2008云服务器安全搭建网站?  微信小程序 require机制详解及实例代码  深圳网站制作的公司有哪些,dido官方网站?  DeepSeek是免费使用的吗 DeepSeek收费模式与Pro版本功能详解  千问怎样用提示词获取健康建议_千问健康类提示词注意事项【指南】  北京网页设计制作网站有哪些,继续教育自动播放怎么设置?  制作公司内部网站有哪些,内网如何建网站?  教你用AI润色文章,让你的文字表达更专业  phpredis提高消息队列的实时性方法(推荐)  Laravel怎么实现验证码功能_Laravel集成验证码库防止机器人注册  详解MySQL数据库的安装与密码配置  Laravel如何设置定时任务(Cron Job)_Laravel调度器与任务计划配置  Java遍历集合的三种方式  Laravel怎么使用Markdown渲染文档_Laravel将Markdown内容转HTML页面展示【实战】  Laravel Fortify是什么,和Jetstream有什么关系  Win11怎么设置默认图片查看器_Windows11照片应用关联设置  Laravel如何使用API Resources格式化JSON响应_Laravel数据资源封装与格式化输出  如何彻底卸载建站之星软件?  ,交易猫的商品怎么发布到网站上去?  php结合redis实现高并发下的抢购、秒杀功能的实例  Laravel如何使用Telescope进行调试?(安装和使用教程)  移动端脚本框架Hammer.js  深圳网站制作平台,深圳市做网站好的公司有哪些?  Laravel如何生成API文档?(Swagger/OpenAPI教程)  Laravel如何实现图片防盗链功能_Laravel中间件验证Referer来源请求【方案】  edge浏览器无法安装扩展 edge浏览器插件安装失败【解决方法】  如何在 React 中条件性地遍历数组并渲染元素  Linux网络带宽限制_tc配置实践解析【教程】  在Oracle关闭情况下如何修改spfile的参数  Laravel如何处理异常和错误?(Handler示例)  Laravel中间件起什么作用_Laravel Middleware请求生命周期与自定义详解  高端建站三要素:定制模板、企业官网与响应式设计优化  Laravel怎么生成二维码图片_Laravel集成Simple-QrCode扩展包与参数设置【实战】  Laravel如何实现全文搜索_Laravel Scout集成Algolia或Meilisearch教程  安克发布新款氮化镓充电宝:体积缩小 30%,支持 200W 输出  如何在阿里云虚拟服务器快速搭建网站?  详解vue.js组件化开发实践  Laravel如何优化应用性能?(缓存和优化命令)  用yum安装MySQLdb模块的步骤方法  如何自定义safari浏览器工具栏?个性化设置safari浏览器界面教程【技巧】  html5如何实现懒加载图片_ intersectionobserver api用法【教程】