zoukankan      html  css  js  c++  java
  • js闭包

    1、什么是闭包?

      函数嵌套函数

      内部函数可以引用外部函数的参数和变量,参数和变量不会被垃圾回收机制收回

    function fn1(){
         var a = 5;
         function fn2() {
              alert(a);             //内部函数使用外部函数的变量,不会被垃圾回收机制回收
         }  
         return fn2;
    }
    
    var c = fn1();
    c();
    /*
      结果:5
      fn1(),返回结果为fn2函数,即function fn2() { alert(a) };
      c(),调用fn2函数
      
      也可以这样写:fn1()(),fn1()=fn2
    */

    2、闭包的好处?应用在哪里?

      好处:

        希望一个变量长期驻扎在内存当中

        避免全局变量的污染

        私有成员的存在

    /*全局变量*/
    var a = 1;
    function fn(){
    a
    ++; alert(a); } fn(); //2 fn(); //3 alert(a); //3 /*将以上改写成局部变量*/ function fn() { var a = 1; a++; alert(a); } fn(); //2 fn(); //2 alert(a); //出错 //以上结果是因为被垃圾回收机制回收了 /*a为局部变量,a又可以累加,采用闭包的方法*/ function fn1(){ var a = 1; function fn2() { a++; alert(a); } return fn2; } var c = fn1(); c(); //2 c(); //3 alert(a); //出错,因为是局部变量


    //以上改写成如下:
    function fn1(){
    var a = 1;
    return function(){
    a++;
    alert(a);
    }
    }

    var c = fn1();
    c(); //2
    c(); //3
    alert(a) //出错,因为是局部变量


    /*
    函数声明:
      function fn(){
    alert(1);
    }
    函数调用:
    fn();

    将“函数声明”改写成“函数表达式”:前面加上括号,括号内部为函数,需要调用直接后面加上括号,如下:
       (function (){
    alert(1);
    })();
    */

    //改写代码

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

    //以上的情况,模块化代码,减少全局变量的污染
    //私有成员的存在
        var test = (function(){
                var a = 1;
                function fn1(){
                    a++;
                    alert(a);
                }
                function fn2(){
                    a++;
                    alert(a);
                }
                return {
                     b:fn1,
                     c:fn2
                }
            })();
    
            test.b();  //2
            test.c();  //3
            alert(a);  //出错
            alert(fn1());  //出错
            alert(fn2());    //出错
    
    //变量a、函数fn1和fn2为私有,以上为模块化代码的模式

       用法:

        模块化代码

        在循环中直接找到对应元素的索引

    3、闭包需要注意的地方

      IE下会引发内存泄漏 

      (当页面跳转时,变量不会释放,一直存在内存当中,使CPU一直在累加,只有当浏览器关闭时才释放内存)

      满足条件,如下例:一个变量(oDiv)获取DOM节点或数组对象的时候,它的一个属性(onclick)引用一个内部函数,而内部函数中这个变量(oDiv)又去引用外部的变量(oDiv),会产生内存泄漏

      

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

      //解决内存泄漏问题
      window.onunload = function(){
    oDiv.onclick = null;
    } }

    方法二:
    window.onload = function(){
    var oDiv = document.getElementById('div');
     var id = oDiv.id;
     oDiv.onclick = function(){
    alert(id);
    }
    oDiv = null;
    }

  • 相关阅读:
    SQLite Select语句的意外发现
    和一个经理人谈话的经典语句
    [转]如何动态增长一个数组的大小
    [转]Spring AOP中文教程
    为Wildfish框架增加方法调用日志[Aspectsharp]
    第四周学习心得
    《大道至简:软件工程实践者的思想》观后感
    第三周学习心得
    暑假第一周Java学习心得
    第二周学习心得
  • 原文地址:https://www.cnblogs.com/joya0411/p/3598762.html
Copyright © 2011-2022 走看看