JS中的闭包

  对于闭包,普遍的说法是“函数嵌套的函数”,我认为,可以理解为可以调用外部变量的函数,在ECMAScript中有提到,使用全局变量是一个简单的闭包实例。内部函数就是一个闭包,因为它可以获取外部函数的参数及变量,全局变量的值。

  闭包的作用在于:1.解决因垃圾回收机制而使局部变量无法长期驻扎在内存中的问题;

          2.减少全局变量的污染;

      它可以:1.实现变量的累加;2.在循环中找到对应元素的索引;3......(还有很多)


  那什么是垃圾回收机制呢?

  JS为了减少内存占用,函数的局部变量在函数调用后会被清除

  function aaa () {

    var a = 1;

    a++;

    alert(a);

  }

  aaa(); //2

  aaa(); //2

  可以看出,调用后变量a被清除,再次调用时才被赋值,因此无法实现累加的效果,可通过闭包实现累加。


      什么是全局变量污染呢?

  var a = 1;

  function aaa () {

    a++;

    alert(a);

  }

  aaa(); //2

  aaa(); //3

  alert(a); //3

  可以看出,此时虽然可以实现累加,但是全局变量被改变,即此时全局变量a只能被函数aaa()使用,不可以其他函数使用,否则互相修改,不确定且变化的值会使程序功能的实现出现问题。


  闭包的写法又是怎样的呢?

  function aaa () {

    var a = 1;

    return function () {

      a++;

      alert(a); 

    }

  }

  var b = aaa ();

  b(); //2

  b(); //3

  此时a为局部变量,所以不会污染的全局变量~


  闭包还有个不错的用法:模块化代码

  作用:将内部函数私有(利用括号将函数变为自执行的函数表达式)

  (function aaa () {

    //do something...  

  })() //可传参

      还可以这样:

  var aaa = (function () {

    var a = 1; //私有成员

    function bbb () {  //私有方法bbb

      a++;

      alert(a);

    }

    function ccc () {     //私有方法ccc

      a++;

      alert(a);

    }

    return{

      b:bbb,

      c:ccc

    }

  })();

  aaa.b(); //2

  aaa.c(); //3

  alert(a); //报错

  alert(bbb); //报错

  alert(ccc);  //报错


  气人的IE,委屈的闭包

  差点忘了,闭包也不都是好的,由于早期IE的垃圾回收机制是使用引用计数垃圾回收的方式,简单的说就是使用一个计数器记录数据被引用的次数,如果为0则清除,这样当有互相引用的情况出现时就会出现内存泄漏,所谓的内存泄漏,即计数器不会为0,只要浏览器不被关闭就不会被清除,一直留在内存中,我们可以看到的就是浏览器越来越慢越来越慢,可你就是不知道浏览器到底发什么疯得什么病了,如果是你自己的网站,那最好看看是否是内存泄漏了~

  互相引用的情况:dom节点或获取的数组对象的属性引用内部函数,内部函数的变量又引用外部时就会出现互相引用的情况,此时就会出现内存泄漏。

  例子:

    window.onload = function () {

      var oDiv = document.getElementById ('div1');    //dom元素

      oDiv.onclick = function () {     //被引用

        alert (oDiv.width); 

      };

    };

  解决方案1:

  window.onunload = function () {

    oDiv.onclick = null;   //在关闭网页时清空回收

  };

  解决方案2:

  window.onload = function () {

    var oDiv = document.getElementById('div1');

    var w = oDiv.width;

    oDiv.onclick = function () {

      alert (w);

    };

    oDiv = null;  //清空,使被回收

  };

  至于HTML,CSS部分,请自行脑补~

posted @ 2014-04-01 16:54  Pada  阅读(208)  评论(0编辑  收藏  举报