for循环+setTimeOut的经典面试问题

1 篇文章 0 订阅

for循环+setTimeOut的经典面试问题

前段时间去面试的时候,遇到一道面试题,有关于for循环和setTimeOut的问题,其中还关乎var和let的区别。详情请看这个链接

setTimeOut和setInterval的执行机制

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

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

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

如下例所示:

for(var i=0;i<3;i++){
	setTimeout(function(){
		alert(i);},1000)
	}

结果:在一秒之后,同时输出3个3

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

面试题

分别求下面两个代码块的执行结果

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

结果:5 5 5 5 5

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

结果:隔一秒输出,值分别为0 1 2 3 4

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

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

块级作用域和函数作用域的区别

块级作用域和函数作用域的区别

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值