javascript 闭包

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title>无标题文档</title>
<script type="text/javascript">
//1:什么是闭包?  函数嵌套函数,内部函数可以引用外部函数的参数和变量,参数和变量不会被垃圾回收机制收回。
  function aaa(a)
  {
         var b=5
        function bbb()
        {
            alert(a);
            alert(b)
        }
  }
  aaa(); //执行完毕后变量a,b不会被垃圾回收机制收回
  
  //js中的垃圾回收机制
  function ccc()
  {
    var a=1;
  }
  ccc();//执行完毕变量a被垃圾回收机制回收*/
  
  function ddd()
  {
     var a=5;
     function eee()
     {
        alert(a);
     }
     return eee;
  }
  var c=ddd();//执行完毕变量a未被垃圾回收机制回收
   c();  //5   变量a还存在
   
   
   
   //2:闭包的好处: a:希望一个变量长期驻扎在内存中, b:避免全局变量的污染,c:私有成员的存在。
   
     var a=1;
     function aaa()
     {
         i++;
         alert(a);
     }
   aaa()    //2
   aaa()    //3    
   alert(a)    //因为a是全局变量所以还能找到  
   
   
   
   //提高性能避免全局变量
   function  aaa()
   {
      var a=1;
      a++;
      alert(a);
   } 
   
   aaa();  //2   
   aaa();  //2   调用一次后被回收,所以依然是2
   
   //a是局部变量,同时做到累加,闭包能做到。
   function aaa()
   {  
       var a=1;
       return function()
       {
           a++;
           alert(a);
       }
   }
   
   var b=aaa();
   b();   //2
   b();   //3 
   alert(a)  //报错,因为a是局部变量
   
   
   //函数声明改为函数表达式,
   function aaa()  //函数声明
   {
      alert(1);
   }
   aaa();
   
   ( function aaa()  //函数表达式
   {
      alert(1);
   })();  //自执行
   
    ( function()  //函数表达式,可以不需要名字,因为我只需让它执行
   {
      alert(1);
   })();
   
   
   //改写上面的闭包 ,叫做模块化代码
   var aaa=(
      function()
      {
          var a=1;
          return function()
          {
             a++;
             alert(a);
          } 
      }
   
   )();
   
   aaa(); //2
   aaa(); //3
   
   
   //私有成员的存在,模块化代码
   var aaa=(
       function()
       {
           var a=1;
           
           function bbb()
           {
              a++;
              alert(a);
           }
           function ccc()
           {
              a++;
              alert(a);
           }
           
           return {
           
               b:bbb,
               c:ccc
           }
       
       }
   )();
   
   aaa.b();  //2
   aaa.c();   //3
   
   //在循环中找到对应的索引
   window.onload=function()
   {
       var aLi=document.getElementsByTagName('li');
       for(var i=0;i<aLi.length;i++)
       {
           aLi[i].onclick=function()
           {
               alert(i);    //2 点击每个都会弹出2,因为我点击时循环已经结束
           }
           
           //利用壁包改写
           (function(i){
                aLi[i].onclick=function()
               {
                    alert(i)
               }
           })(i);
           
           //另一种改写
             aLi[i].onclick=(function(i){
                 return function()
                 {
                    alert(i);
                 }
             })(i);
          
       }
   
   
      //3:IE下会引发内存泄漏
        var oDiv=document.getElementById('div1');
        
        oDiv.onclick=function()  //因为onclick属性引用了function函数,
        {                         
            alert(oDiv.id);       //而function内部的oDiv.id又引用了外部的oDiv对象,互相引用,所以会内存泄漏。
        }
      
        //解决方法一:
        window.onunload=function()
        {
            oDiv.onclick=null;
        }
        
        //解决方法二:
        var oDiv=document.getElementById('div1');
        
        var id=oDiv.id;
        oDiv.onclick=function()
        {
           alert(id);
        }
        oDiv=null;
        
   }
  
   
   
   
</script>
</head>

<body>
<div id="div1"></div>
<ul>
<li>111</li>
<li>222</li>
<li>333</li>
</ul>
</body>
</html>

 

posted @ 2013-05-13 20:43  zhangchun  阅读(250)  评论(0编辑  收藏  举报