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;
}

原文地址:https://www.cnblogs.com/joya0411/p/3598762.html