简单说说我理解的js中的闭包

  如果您已经知道了js中的闭包是怎么一回事,那么您可以不用看(大家的时间都很宝贵的),这篇文章可能对您的意义不大,当然如果您看完这篇文章后,发现其中有错误的地方,希望您能给指正一下,在此我先谢过了。

  那么开始吧:

  那么什么是闭包呢?专业术语咱也说不出来,在js中的我的理解就是函数嵌套函数,例如这样的

	function xx(){
		function yy(){
		
		};
	};
	

   那么闭包有什么用呢?

代码片段
 1 <script type="text/javascript">
 2 //内部函数可以调用外部函数的参数和变量,参数和变量是不会垃圾回收机制回收的,也就是说b的值会一值在内存当中
 3     function xx(){
 4         var b=3;
 5         function yy(){
 6             alert(b);
 7         };
 8         return yy;
 9     };
10 
11        var zz=xx();
12        zz();
13 
14 </script>

  下面再来看两段代码 

代码片段
1 <script type="text/javascript">
2         var a=1;//全局变量,使用全局变量会影响程序性能
3     function xx(){
4         a++;
5         alert(a);
6     }
7     xx();//弹出2
8     xx();//弹出3
9  </script>

 

代码片段
1 <script type="text/javascript">
2 function xx(){
3     var aa=1;//局部变量
4     aa++;
5     alert(aa);
6     }
7     xx();//只会弹出2
8     xx();//真的挺2
9 </script>

  下面我就来说说问什么我要写这两段代码了,就像注释中提到的全局变量会影响到程序性能,所以在好多语言写的程序中都不推荐怎么使用的,只有在必要的时候才会使用,但是上面的代码片段二却实现不了让a++的效果,那怎么办呢,现在闭包出场了

代码片段
 1 <script type="text/javascript">
 2 function xx(){
 3         var a=1;
 4         return function(){
 5         a++;
 6         alert(a);
 7         }
 8     };
 9     
10 var xxx= xx();
11     xxx();//窗口弹出2
12     xxx();//窗口弹出3
13  </script>

   当然我们可以简化它(匿名方法)

代码片段
 1 <script type="text/javascript">
 2 var xxx=(function(){
 3         var a=1;
 4         return function(){
 5         a++;
 6         alert(a);
 7         };
 8     })();
 9     
10     xxx();
11     xxx();
12 </script>

  闭包还可以把成员私有化:

代码片段
 1 <script type="text/javascript">
 2     var xx=(function (){
 3         var a=10;
 4         function yy(){
 5             a++;
 6             alert(a);
 7         };
 8         function zz(){
 9             a++;
10             alert(a);
11         };
12         
13         return {
14             y:yy,
15             z:zz
16         };
17     })();
18     xx.y();//窗口弹出11
19     xx.z();//窗口弹出12
20 </script>

  在上面的代码中,你是取不到a的值,以及yy和zz这两个函数的.

由于闭包可以把变量参数存于内存当中,即使你跳转页面也还会存在,这就引发了内存泄漏,除非你关闭浏览器,它才会自动释放,那么下面我们就来看看防止内存泄漏的方法:

代码片段
 1 <head>
 2 <meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
 3 <title>无标题文档</title>
 4 <script type="text/javascript">
 5     window.onload=function(){
 6         var oDiv=document.getElementById('div1');
 7          oDiv.onclick=function(){
 8              alert(oDiv.id);
 9          };
10          window.onunload=function(){
11         oDiv.onclick=null;
12     };
13          
14     };
15     
16 </script>
17 </head>
18 
19 <body>
20     <div id="div1" style="background-color:#FF0000">dd</div>
21 </body>

  更多防止内存泄漏的方法大家可以参考carekee(博客园内的一位哥们写的)的方法:http://www.cnblogs.com/carekee/articles/1733847.html

  下面我们来一个常见的闭包用法:

Html代码
<body>
    <ul>
        <li>aaaaaaaaaaa</li>
        <li>bbbbbbbbbbb</li>
        <li>cccccccccccccc</li>
        <li>bbbbbbbbbbb</li>
    </ul>
</body>
代码片段
 1 <script type="text/javascript">
 2     window.onload=function(){
 3         var oLis=document.getElementsByTagName('li');
 4         for(var i=0;i<oLis.length;i++){
 5             oLis[i].onclick=function(){
 6                 alert(i);//弹出来的总是4,为什么呢?
 7             };
 8         }
 9         
10     };
11 </script>

  因为onclick事件是当你点击的时候才会触发的,但是当你点击的时候for循环早就执行完毕了,所以每次点击都是最后一个值,说漏了,在执行for循环的时候其实function(){alert(i);};是没有执行的,您可以用火狐调试看看.

  那么怎么样才能让它弹出0,1,2。。。呢? "√"就是闭包

代码片段
 1 <script type="text/javascript">
 2     window.onload=function(){
 3         var oLis=document.getElementsByTagName('li');
 4         for(var i=0;i<oLis.length;i++){
 5         (function(i){
 6             oLis[i].onclick=function(){
 7                 alert(i);//这次就依次弹出0,1,2,3了
 8             };
 9         })(i);
10             
11         }
12         
13     };
14 </script>

  当然还有别的很多方法,感兴趣的朋友可以在园子里搜索一下。

  最后唠叨一下,以上就是个人简单的一些理解都是表面上的一些基础知识,因为是学生而且都没老师,只能自己慢慢摸索,所以当中必然有很多错误,望大家能给予批评指正,再次感谢大家了,祝大家工作顺利,身体健康!

 

posted @ 2012-08-29 12:35  一抹、思乡泪  Views(5320)  Comments(2Edit  收藏  举报