JS闭包

闭包

闭包的特点:
1、函数嵌套函数
2、内部函数引用外部函数的变量或形参
3、内部函数应用的外部函数的变量或形参不会再外部函数执行完毕后清空,而是会继续存储在内存空间,以满足内部函数的调用,(即不会被垃圾回收机制回收)。


缺点:由于第三点特点的原因,闭包会造成内存泄漏,变量占据内存空间用完之后还是不会将内存空间释放,导致该内存一直出于占用状态。
解决方法,在页面加载完成后,手动释放闭包占用的私有内存。

 

function aaa(a){
  var b = 20;
  function bbb(){
    alert(a + "," + b);
  }
  return bbb;
}
var res = aaa(10);
res();
alert(a + "," + b);

例题详解:声明一个外部函数aaa,在aaa函数中内嵌一个内部函数bbb,其中bbb内部函数引用了外部函数aaa的形参a和变量b,所以外部函数中的变量和形参在外部函数执行完成后不会清空,而是以私有内存的形式在内存中存贮,以备内部函数的调用。这里的私有内存的意思就是,该内存是只有内部函数bbb调用的时候才可以访问,其他任何方式都不能访问该内存,因此上述代码的末尾alert语句会出现a,b is not defined的错误。

上述介绍中可以看出吗,闭包的优势就是:可以将一个变量常驻内存,作为一个私有成员,它不会造成全局污染,只给需要用到它的函数可见,其他一律不可见

例题前言:首先我们要知道写程序中声明全局变量是一件非常危险的事情。但是我们在有些时候却需要多个函数同时操作的变量,为了避免使用全局变量,我们就可以使用闭包,比如变量累加:

function aaa(){
  var a = 0;
  function bbb(){
    a++;
    console.log(a);
  }
  return bbb;
}
var res = aaa();
res();
res();


闭包的标准写法

var res = (function(){
    var a = 0;
    return function(){
        a++;
        console.log(a);
    }
})();
res();
res();
res();       

匿名函数介绍:顾名思义没有名字的函数,不需要使用函数名调用,声明后直接执行,也叫立即执行函数


上面介绍完闭包实现变量的私有化,接下来闭包实现函数私有化

var module = (function(){
    var a = 0;
    var b = 9;
    function aaa(){
        a++;
        console.log(a);
    }
    function bbb(){
        b--;
        console.log(b);
    }
return {funcA:aaa,funcB:bbb};
})();
module.funcA();
module.funcB();
module.funcA();
module.funcB();   

 


闭包实战:在循环中找到索引
常规写法:声明一个属性记录当前下标

window.onload = function(){
    var aBtns = document.getElementsByTagName("button");
    for(var i = 0; i < aBtns.length;i++){
        aBtns[i].index = i;
        aBtns[i].onclick = function(){
            alert(this.index);
        }
    }
}

闭包:

window.onload = function(){
  var aBtns = document.getElementsByTagName("button");
    for(var i = 0;i < aBtns.length;i++){
      aBtns[i].onclick = (function(index){
        return function(){
          alert(index);
        }
      })(i)
    }
}

闭包分析:首先外层函数是一个立即执行函数,该函数的返回值是一个内部函数,我们将外部函数的返回值赋给了click这个事件。也就是说该程序就是通过循环给每一个button的点击事件添加一个绑定函数,而这个绑定函数就是通过外部函数返回的内部函数。

 

接下来讲闭包的最后一个问题,就是闭包的缺点
其实这个缺点同时就是闭包最大的优势的副作用,由于闭包会出现变量常驻内存,这样就会造成内存泄漏,解决方法就是在页面关闭或刷新的时候将闭包产生的常驻内存变量清空。具体如下:

window.onload = function(){
  var oDiv = document.getElementById("div1");
  oDiv.onclick = function(){
    alert(oDiv.id);
  }
  window.onunload = function(){
    oDiv.onclick = null;
  }
}

内存泄漏简介:
JavaScript是一种具有垃圾回收机制的语言——对象在创建时分配内存,然后当这个对象的引用计数为零时,浏览器会回收内存。宿主环境提供的对象都是按照这种方法被处理的。
浏览器主机需要处理大量的对象来描绘一个正在被展现的HTML页面——DOM对象。浏览器负责管理他们的内存分配和回收。
IE浏览器有自己一套垃圾回收机制,这套机制与JavaScript提供的垃圾回收机制交互时,可能发生内存泄漏。
在IE中,每当在一个JavaScript对象和一个本地对象之间形成循环引用时就会发生内存泄漏。

posted @ 2019-03-29 15:09  丁沉~  阅读(135)  评论(0)    收藏  举报