+ -
当前位置:首页 → 问答吧 → 闭包函数绝对难题

闭包函数绝对难题

时间:2011-08-31

来源:互联网

JScript code
 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.。。。

请问为什么?????

作者: xjl756425616   发布时间: 2011-08-31

这是闭包的基本性质。。

作者: knightzhuwei   发布时间: 2011-08-31

我想知道不加的话,为什么会报错,,按程序流程不应该错啊

作者: xjl756425616   发布时间: 2011-08-31

首先你得理解JS的作用域链的关系,JS中的作用域是由最里层到最外层的搜索,比如内部函数引用了一个a变量,如果内部函数中不存在a,则继续在包含这个内部函数的外部函数中搜索,这种关系一直延伸到全局变量为止。
(function(){}());是匿名函数,匿名函数是定义就执行,这里的外部循环就可以看做一个外部的函数,循环中的匿名函数属于内部函数,而setTimeout又属于匿名函数的内部函数。
刚才说过,匿名函数定义就会执行,那么每次循环的时候 pos得到的绝对是正确的i值(不是最终的100),
既然匿名函数中已经存在pos值,那么setTimeout就不会再延伸到循环中去搜索i的值为多少,所以每次你得到的是一个正确的值。

有一点必须明白,闭包中存在着一个活动对象,这个活动对象保存着对闭包中引用的外部变量,没有匿名函数的情况下,活动对象保存的是i值,而当你调用setTimeout的时候,就会去查询活动对象中的i值为多少,这个时候i已经被执行完毕,所以等于100,而有匿名函数的情况下,活动对象保存的是匿名函数中的pos,这个pos因为每次都被匿名函数执行过,所以保存的不是最终的100..

理解这种闭包,最重要的就是理解作用域链。。。。。

作者: koo42636880   发布时间: 2011-08-31