• 闭包总结


     

     


    闭包的优点:


    1、匿名自执行函数,模拟块级作用域,避免污染全局变量 

    (function(){
    var a=100;
    function F1(){
        alert(a);
    }
    function F2(){
        alert(a);
    }
    F1(); //100
    F2(); //100
    })(); 
    alert(a)

    2、缓存

    function f(){
    var a=100;
    return function(){ a++;alert(a);}
    }
    var F=f();
    F();//101
    F();//102

    3 、实现封装

    function Person(){     
        var a = 100;             
        this.get=function(){    
            return a;  
        };  
    }  
    var P=new Person();
    alert(P.get());

     闭包的缺点:


    1.占用内存

    通常来说,函数的活动对象会随着执行期上下文一起销毁,但是,由于闭包引用另外一个函数的活动对象,因此这个活动对象无法被销毁,这意味着,闭包比一般的函数需要更多的内存消耗。

    2.内存泄露

    由于IE使用非原生javascript对象实现DOM对象,因此闭包会导致内存泄露问题,例如:在IE9之前,如果闭包的作用域链中保存着一个HTML元素,那么意味着该元素无法被销毁。

    /*这里DOM对象element引用闭包函数,闭包函数作用域引用DOM对象,循环引用导致内存泄露。*/
    
    function closure(){  
    var element=document.getElementById("elementID");  
      element.onclick=function(){  
            alert(element.id);  
      }  
     }  
    
    /*解决方法:先把element.id用局部变量id保存起来,并且在闭包中引用该变量消除了循环引用。
    但是,这样还不能消除内存泄露,闭包会引用包含函数的活动变量,而其中会有element。
    即使闭包闭包不直接引用element,包含函数的活动对象仍然会保存一个引用,因此有必要把element设为null。*/ function closure(){ var element=document.getElementById("elementId"); var id=element.id; element.onclick=function(){ alert(id); } element=null; }


    3.性能问题

    使用闭包时,会涉及到跨作用域访问,每次访问都会导致性能损失。
    因此在脚本中,最好小心使用闭包,它同时会涉及到内存和速度问题。不过我们可以通过把跨作用域变量存储在局部变量中,然后直接访问局部变量,来减轻对执行速度的影响。


     例子:


    eg1、this指向

    //this对象是在运行时基于函数的执行环境绑定的。
    
    var name="Window";  
    var object={  
          name: "my object",  
          getName: function(){  
            return function(){  
                  return this.name;  
               }  
            }  
       }  
    alert(object.getName()());   //window  
    
    /*每个函数被调用时都会取得两个特殊变量:this和arguments。
    内部函数搜索这两个变量时,只会搜索到其活动对象为止,因此,不可能直接访问外部函数的这两个变量。
    不过将外部作用域中的this保存在一个闭包能够访问的变量里,就可以访问该对象了。*/

    var name="window"; var object={ name : "my object", getName:function(){ var that=this; return function(){ return that.name; } } }
    alert(object.getName()()); //my object

    eg2、循环闭包

    <div class="clickBox">1</div>
    <div class="clickBox">2</div>
    <div class="clickBox">3</div>
    <div class="clickBox">4</div>
    <div class="clickBox">5</div>
    <div class="clickBox">6</div>

    <script type="text/javascript">
    var clickBoxs = document.querySelectorAll('.clickBox');
    for (var i = 0; i < clickBoxs.length; i++){ 
    /*
    clickBoxs[i].onclick = function(){console.log(i);};//问题
    clickBoxs[i].onclick = (function(i){return function(){console.log(i);};})(i);//解决1 
    */
    clickBoxs[i].onclick =f(i);//解决2.1
    }
    function f(i){return function(){console.log(i);};}//解决2.2
    </script>

    eg3.在函数执行之前为要执行的函数提供具体参数:settimeout

    var a=222;
    //不传参数时
    setTimeout(function(){alert(a)},500);//正确
    
    //传参数时
    setTimeout(function(a){alert(a)},500);//undefined,传参失败
    
    function f(obj){alert(obj)}
    setTimeout(f,500);//undefined,传参失败
    setTimeout(f(a),500);//参数无效,传参失败
    
    //正确做法,使用闭包
    function F(obj){return function(){alert(obj)}}
    var f=F(a);
    setTimeout(f,500);//正确

     

  • 相关阅读:
    日钢信息自动化质保书打印系统应用实践《全国冶金自动化信息网2012年年会论文集》2012年
    MySQL :: MySQL 5.0 Reference Manual :: 20.1.4.5 Configuring a Connector/ODBC DSN on Unix
    Fast JavaScript Max/Min
    js javascript:void(0)
    dom querySelector
    php输出Json
    精通javascript:永不终止的blog
    javascript事件委托event delegation
    js+css Text Blocks Over Image(文字覆盖在图片上)
    一个javascript选项卡的进化史
  • 原文地址:https://www.cnblogs.com/taoxiaodan/p/6390602.html
Copyright © 2020-2023  润新知