zoukankan      html  css  js  c++  java
  • 闭包

    1.什么是闭包?

    (1)函数嵌套函数

    (2)内部函数可以引用外部函数的参数和变量

    (3)参数和变量不会被垃圾回收机制所收回。因为内部函数bbb还在被引用着,所以需要长期驻扎在内存中。

    function aaa(a){
      var b=5; 
      function bbb(){
         alert(a);
         alert(b);  
    }   
    }
    
    aaa();//a和b都是可以访问的到的

    这就是闭包

    function aaa(){
        var a = 5;
        function bbb(){
            alert(a);
        }
        return bbb;
    }
    
    var c = aaa();//因为aaa()函数返回的是bbb
    
    c();//此时c()就相当于bbb()

    返回的结果就是:5

    2.什么是垃圾回收机制?

    //JS中的垃圾回收机制
    
    function aaa(){
        
        var a = 1;
        
    }
    
    aaa();

    变量a会被JS中垃圾回收机制收回,就不存在了。

     3.闭包有什么好处?应用在哪里?

    好处:(1)希望一个变量长期驻扎在内存当中
       (2)避免全局变量的污染
            (3)私有成员的存在

    栗子1:全局变量的污染:a是全局变量

    var a = 1;
    function aaa(){
        a++;
        alert(a);
    }
    
    aaa();  //2
    aaa();  //3
    
    alert(a);//3

    栗子2此时a是局部变量,每执行一次,就进入垃圾回收机制,所以每次执行aaa()函数,结果都是2

    function aaa(){
        var a = 1;
        a++;
        alert(a);
    }
    aaa();  //2
    aaa();  //2

    栗子3:利用闭包,变量a是局部变量

    function aaa(){
        var a=1;
        return function(){
            a++;
            alert(a);
        }
    }
    
    var b=aaa();
    b();  //2
    b();  //3
    alert(a); //a is not defined,因为a不是全局变量,访问不到a

    用法:
    1.模块化代码
    2.在循环中直接找到对应元素的索引

    栗子4:模块化代码

    function aaa(){
        alert(1);
    }
    aaa();
    
    //这两个函数结果是一样的,不同的是下面的(function(){
        alert(1);
    })是一个函数表达式
    
    (function(){
        alert(1);
    })();
    var aaa=(function(){
        var a=1;
        return function(){
            a++;
            alert(a);
        }
    })();
    aaa();  //2
    aaa();  //3

    栗子5有私有成员的存在,变量a,函数bbb(),函数ccc()

    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,为什么是3呢?因为a相对于bbb函数和ccc函数,是全局变量,所以函数bbb执行后,a=2了,再执行ccc函数就是3了

     栗子6:在循环中直接找到对应元素的索引

    方法一:

    <!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=utf-8" />
    <title>无标题文档</title>
    <script>
    window.onload = function(){
        var aLi = document.getElementsByTagName('li');
        for(var i=0;i<aLi.length;i++){
            (function(i){
    
                aLi[i].onclick=function(){
                    alert(i);
                }
            })(i);//将i参数传进去,存在内存中。
        }
    
    };
    
    </script>
    </head>
    
    <body>
    <ul>
        <li>11111111111</li>
        <li>11111111111</li>
        <li>11111111111</li>
    </ul>
    </body>
    </html>

    这样得到的结果是,点击哪一个按钮,就弹出那个位置的索引

    方法二:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>索引</title>
        <script>
            window.onload=function(){
                var lis=document.getElementById('test').getElementsByTagName('li');
                for(var i=0;i<lis.length;i++)
                {
                    lis[i].index=i;
                    lis[i].onclick=function(){
                        alert(this.index);
                    };
                }
            }
        </script>
    </head>
    <body>
        <ul id="test">
            <li>这是第一条</li>
            <li>这是第二条</li>
            <li>这是第三条</li>
        </ul>
    </body>
    </html>

    4.闭包需要注意的地方?

    在IE下有可能闭包引发的内存泄露问题及解决方案

    内存溢出 out of memory,是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory;比如申请了一个integer,但给它存了long才能存下的数,那就是内存溢出。

    内存泄露 memory leak,是指程序在申请内存后,无法释放已申请的内存空间,一次内存泄露危害可以忽略,但内存泄露堆积后果很严重无论多少内存,迟早会被占光。

    memory leak会最终会导致out of memory!

    内存溢出就是你要求分配的内存超出了系统能给你的,系统不能满足需求,于是产生溢出。 

        内存泄漏是指你向系统申请分配内存进行使用(new),可是使用完了以后却不归还(delete)结果你申请到的那块内存你自己也不能再访问(也许你把它的地址给弄丢了),而系统也不能再次将它分配给需要的程序。一个盘子用尽各种方法只能装4个果子,你装了5个,结果掉倒地上不能吃了。这就是溢出!比方说栈,栈满时再做进栈必定产生空间溢出,叫上溢,栈空时再做退栈也产生空间溢出,称为下溢。就是分配的内存不足以放下数据项序列,称为内存溢出. 

    栗子7:这样就会引发内存泄漏,除非关掉浏览器。

    window.onload = function(){
    	var oDiv = document.getElementById('div1');
    	
    	oDiv.onclick = function(){
    		alert(oDiv.id);
    	};
    

    为什么这样会引发内存泄漏?

    因为dom已经获取到了div1的节点,下面的oDiv的属性onclick里面的函数又存在访问oDiv的属性id,这样就形成了内存泄漏。

    解决方案:

     第一种:

    window.onload = function(){
        var oDiv = document.getElementById('div1');
        
        oDiv.onclick = function(){
            alert(oDiv.id);
        };
        
        window.onunload = function(){
            oDiv.onclick = null;
        };
        
    };

    onunload 事件在用户退出页面时发生。页面退出时,将onclick属性释放。

    第二种:将需要用的id先获取到,最后将oDiv释放。

    window.onload = function(){
        var oDiv = document.getElementById('div1');
        
        var id = oDiv.id;
        
        oDiv.onclick = function(){
            alert(id);
        };
        
        oDiv = null;
        
    };
  • 相关阅读:
    Apache Ant 1.9.1 版发布
    Apache Subversion 1.8.0rc2 发布
    GNU Gatekeeper 3.3 发布,网关守护管理
    Jekyll 1.0 发布,Ruby 的静态网站生成器
    R语言 3.0.1 源码已经提交到 Github
    SymmetricDS 3.4.0 发布,数据同步和复制
    beego 0.6.0 版本发布,Go 应用框架
    Doxygen 1.8.4 发布,文档生成工具
    SunshineCRM 20130518发布,附带更新说明
    Semplice Linux 4 发布,轻量级发行版
  • 原文地址:https://www.cnblogs.com/GumpYan/p/5695460.html
Copyright © 2011-2022 走看看