JavaScript闭包

来源:互联网 发布:横截面数据举例 编辑:程序博客网 时间:2024/05/29 07:51

参考http://www.cnblogs.com/dolphinX/archive/2012/09/29/2708763.html

1、首先举个例子

现在有一个页面


<ul><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li></ul>

如果想给每个li绑定一个点击事件应该怎么做

var oLi = $("li");for(var i=0;i<oLi.length;i++){oLi[i].click(function(){    alert(i);});}


如果按照上面这种方式书写程序,那么每次弹出的都将是4,这个很好理解,因为在运行这段程序的时候,i确实是从0取到了4,每次循环的时候也都将i值赋给了匿名函数,这个也没错,但是每次循环给匿名函数的值都是同一个内存里出来的值。那么,这意味着,等页面加载完毕,我点击任一时间的时候,你们函数都会调用i,而这时候i等于多少?等于4!这导致每次弹出的都是i。那么更改成如下的方式又会是怎样的情形呢?

var oLi = $("li");for(var i=0;i<oLi.length;i++){(function(num){oLi[num].click(function(){})(i);}

下面,我们来捋一捋,每次循环都会调用匿名函数,匿名函数将num作为形参传入,并给每个li绑定点击事件。那么当我点击li的时候,就会调用点击事件的匿名函数,这时候要会用到num,那num来自哪里?num来自外面的匿名函数的形参,在页面加载的时候,每个循环创建了一个匿名函数,一共有五个匿名函数,每个匿名函数各有各的num,因此互不干扰,因此这个num就来自于对应匿名函数的作用域中的num。

2、外部函数vs内部函数

<pre name="code" class="html"><pre name="code" class="html">function outFun(){var i = 0;function innerFun(){      i++;      document.write(i);  }return innerFun;}

如果我想要在页面输出i怎么办?

var global = outFun(); //注意,此时返回的innerFun已经赋给全局变量global了,也就是说innerFun这个内部函数“逃脱了”global();//调用global就如同调用innerFun一样,这时候会输出1

那么问题来了,i不是应该只存在于outFun的内部吗?当在外部的时候不是无法访问的吗?

事实上,i作为局部变量并没有被GC立即回收,因为它还存在着被调用的可能性!!!

也就是说,我们可以通过全局变量来调用内部函数,进而访问函数内部的变量!而在外部函数中创建并返回内部函数,是闭包的常用形式。

0 0
原创粉丝点击