zoukankan      html  css  js  c++  java
  • 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部分,请自行脑补~

  • 相关阅读:
    第5章 JDBC/ODBC服务器
    第4章 SparkSQL数据源
    第3章 SparkSQL解析
    第2章 执行SparkSQL查询
    第1章 Spark SQL概述
    Ubutun重启网卡
    Java面试通关要点汇总整理
    40道Java基础常见面试题及详细答案
    ListView
    数据库表及字段命名规范
  • 原文地址:https://www.cnblogs.com/pada/p/3638678.html
Copyright © 2011-2022 走看看