for(var i=0;i<=100;i+=5)
   {
    (function(){
    var pos=i;
    setTimeout(function(){
    elem.style.height=pos/100*320+"px";
alert(pos);
    },(pos+1)*10)    
    })();
   }我使用alert(pos)观察,发现如果不加(function(){  }();
alert(pos)输出20次100如果加上了,就正确了,显示0 5 10 15.请问为什么?????

解决方案 »

  1.   

    首先你得理解JS的作用域链的关系,JS中的作用域是由最里层到最外层的搜索,比如内部函数引用了一个a变量,如果内部函数中不存在a,则继续在包含这个内部函数的外部函数中搜索,这种关系一直延伸到全局变量为止。
    (function(){}());是匿名函数,匿名函数是定义就执行,这里的外部循环就可以看做一个外部的函数,循环中的匿名函数属于内部函数,而setTimeout又属于匿名函数的内部函数。
    刚才说过,匿名函数定义就会执行,那么每次循环的时候 pos得到的绝对是正确的i值(不是最终的100),
    既然匿名函数中已经存在pos值,那么setTimeout就不会再延伸到循环中去搜索i的值为多少,所以每次你得到的是一个正确的值。有一点必须明白,闭包中存在着一个活动对象,这个活动对象保存着对闭包中引用的外部变量,没有匿名函数的情况下,活动对象保存的是i值,而当你调用setTimeout的时候,就会去查询活动对象中的i值为多少,这个时候i已经被执行完毕,所以等于100,而有匿名函数的情况下,活动对象保存的是匿名函数中的pos,这个pos因为每次都被匿名函数执行过,所以保存的不是最终的100..理解这种闭包,最重要的就是理解作用域链。。
      

  2.   

    3楼正解,不加(function(){})的时候setTimeout还没开始,循环已经或者要结束这时i的值就不容易确定
      

  3.   

    浏览器的执行机制就是这样的你settimeout的时候 一个函数调用请求 在指定的时间后 被放在执行队列里
    一个页面就这样一个队列  也就是 产生 settimeout的 执行函数 不结束的话  不会执行settimeout里的东西反过来 当 settimeout里面的函数执行的时候 i已经是 100 了(以上就是你不加 (function(){})()时候 发生的情况)加了 (function(){})()就是传说中的闭包了  你强制 在一个封闭区域中 执行了 post=i 则 post 的值 是执行时候的 i的值 然后 这个封闭区域的函数不管什么时候执行 对应的post的值 已经固定下来了希望能看的明白
      

  4.   

    这么使用setTimeout, 够笨的的,应该用setInterval