簡單說說我理解的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>

  當然還有別的很多方法,感興趣的朋友可以在園子里搜索一下。

  最后嘮叨一下,以上就是個人簡單的一些理解都是表面上的一些基礎知識,因為是學生而且都沒老師,只能自己慢慢摸索,所以當中必然有很多錯誤,望大家能給予批評指正,再次感謝大家了,祝大家工作順利,身體健康!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM