blog.programfan.info
新网站即将启用

[转]一道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中的事件队列机制。

  1. Kaemter
    2010年12月15日15:54 | #6

    对于Opera与FireFox的输出,如果第二个setTimeout是10的话,输出是4,1,4,2,4,3
    如果是第二个setTimeout是5的话。Opera输出的竟然是1,2,3,4,4,4。真是奇怪,直接搞不懂了。

  2. 李超
    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。

  3. 李超
    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

说句实话,没看懂,先保存起来,过段时间再看

posted @ 2010-12-23 16:55  Gordon Chao  Views(161)  Comments(0Edit  收藏  举报
www.programfan.info
新网站即将启用