[转]一道js小题
var i = 0; while(i++<3){ window.setTimeout(function(){ console.log(i); },0); (function(clouser_i){ window.setTimeout(function(){ console.log('clouser:' + clouser_i); },10); })(i); }
不要运行,解释该代码会输出什么结果,为什么会输出这些结果。
一道小题,两个考点。
一是闭包,二是js中的事件队列机制。
-
2010年12月15日18:48 | #7
Kaemter :
对于Opera与FireFox的输出,如果第二个setTimeout是10的话,输出是4,1,4,2,4,3
如果是第二个setTimeout是5的话。Opera输出的竟然是1,2,3,4,4,4。真是奇怪,直接搞不懂了。个人认为,这个涉及到各个浏览器对setTimeout的细节实现了,比如firefox4.0,经过我多次测试,发现setTimeout的定时器时间值为10或小于10的时候,如果之后紧接着设置了一个setTimeout(fn,0)的定时器,结果会先执行10的定时器,11及以上数值则不会有问题。
而chrome,这个值会变成1,2及以上就不会有问题。
如果要屏蔽掉浏览器的差异性来说这个题目,可以把10改成500。
-
2010年12月16日00:21 | #9
标准答案是444 123
为什么如此,因为第一个setTimeout执行时,while循环已经结束,这涉及到js的单线程模型。
而第二个setTimeout肯定会是123,虽然while也早已执行完了,而且第二个setTimeout定时器执行时,在理论上肯定晚于第一个setTimeout定时器10毫秒(因浏览器对setTimeout的细节实现,只能说是理论上),因为while里执行了匿名函数,创建了闭包环境,clouser_i是绑定在调用对象上的,timeout函数中保存了对clouser_i的引用,所以只有当timeout定时器函数执行完毕,该闭包生命周期才会结束。
引用地址:http://lichaosoft.net/archives/754
说句实话,没看懂,先保存起来,过段时间再看