js的内存释放和java类似,有一个内存回收机制,没有被引用的对象都会被自动释放。而出现闭包的时候会导致变量无法被释放。

function closure(){

   var data = {};

   return function(){

       return data;

   }

}

var closure1 = closure();

closure方法返回的这个方法,在closure1方法每次调用的时候,都可以访问到data对象,反之,data对象的引用没有被释放,否则的话closure1方法将无法访问到data对象。这里可以明显的看出来闭包是会把局部变量引用起来导致无法释放的“副作用”。


var closure2 = closure();

console.log(closure1 === closure2);

false

console.log(closure1() === closure2());

false


从上面的代码可以看出来,closure方法执行两次得到两个方法,这两个方法不是一个方法,两个方法可以访问的data对象也不是同一个对象。也就是说closure执行一次,就有一个新对象data产生,同时生成一个新的方法,返回出去。每次closure方法的执行就导致内存中多了一个data对象,多了一个function(return data),很明显这回导致内存的膨胀。使用不当就会导致内存的泄露。


鉴于这个问题,如非必要应当避免闭包现象的出现。


=========================================================================================

本人在工作中一致在使用jquery作为基本框架,jquery中的一些设计提供的api,适当使用就可以大大降低闭包的出现。

function Component(){

   this.date = new Date();

   var me = this;

   this.clickHandler = function(){alert(me.date)};

}

var component= new Component();

$('#btn').on('click',component.clickHandler)

这一种写法方法,每次new Component()都会产生clickHandler这个方法,这种代码性能就会比较低了。


function Component(){

   this.date = new Date();

}

Component.prototype.clickHandler = function(e){

   var me = e.data;

   alert(me.date);

}

var component= new Component();

$('#btn').on('click',component,component.clickHandler);

第二种写法则避免了每次new Component生成新clickHandler方法的副作用。

类似的$.ajax方法可以接受context参数,也可以达到类似的作用