<script>
function test(){
for(var i=0;i<5;i++){
setTimeout(function(){alert(i)},100);
}
}
test();
function test2(){
for(var i=0;i<5;i++){
(function(i)
{
setTimeout(function(){alert(i)},100);
}
)(i)
}
}
test2();
</script>
请各位师哥帮我解释一下,test()和test2()的执行结果为什么不一样呢?
我正在学习JS对它的编译、解释和执行都不太了解。
希望你们帮我说下JavaScript的编译或者解释和执行的先后顺序,在这提前谢谢您了!

解决方案 »

  1.   

    这个好像是 for 和 setTimeout 之间的配合不一样,用 @A代替一下function(){alert(i)}  大概是,如果一个函数,仍然有指向它的引用的话,就不会被从内存中清除,而且这个函数所在的环境也会被保留下来,
      第一个 @A 在同一个  test() 的环境下,    第二个 @A 则分别在 5个不同的匿名函数的环境下
      

  2.   

    第一个,setTimeout函数是即时返回的,也就是说setTimeout被执行了5次,但是100ms后作为参数的函数才开始一个一个的执行。这时候的i当然就是for里面那个i了。因为for在100ms前就执行完了,所以i的值停在了5,所以alert全是5。
    第二个,唯一不同的是setTimeout放在了一个函数闭包里,这时候i不再指for里面的i,而是指匿名函数里作为参数的i。换种写法:
    (function(x) // <--这个是会被alert出来的

    setTimeout(function(){alert(x)},100);

    )(i) // 这个还是for里面那个i
    同样的所有函数是会在100ms之后被执行,不过因为调用是x,而x在闭包里面,它的值不随外面变化,所以看到的会是0,1,2,3,4.如果参数改成x还用alert(i)的话,这个i才是for里面的i,就会得到和第一种一样的结果。
      

  3.   

    更多闭包的内容请参见:http://www.jslab.org.cn/?tag=ScopeChainAndClosure
      

  4.   

    说反了吧.闭包会保存值?第一个是闭包产生这样的结果,I是在function(){alert(i);}这里的,理论上I的作用范围应该是这个方法里,但I是它外部的变量,这样形成闭包.I是最终循环的值,闭包得到引用,这个引用指向I.第二个,就不是了.使用 (function(){})()第二个括号表示执行了,I当然是当时的值了.说到闭包,函数的作用域链就得清楚.这个问题要自己看些资料,不是三句两句可以说清楚的.
      

  5.   

    function(){
    //do some thing //这就是最原始的函数闭包声明,注意没有函数名
    }
    把"函数入口点"当作参数传递,或者 返回"函数入口点"就是所谓的函数闭包,就是函数指针的东西,还有一些核心的东西,我就不透露了