解决js函数闭包内存泄露问题的办法

本文通过举例,由浅入深的讲解了解决js函数闭包内存泄露问题的办法,分享给大家供大家参考,具体内容如下

原始代码:

function Cars(){
  this.name = "Benz";
  this.color = ["white","black"];
}
Cars.prototype.sayColor = function(){
  var outer = this;
  return function(){
    return outer.color
  };
};

var instance = new Cars();
console.log(instance.sayColor()())

优化后的代码:

function Cars(){
  this.name = "Benz";
  this.color = ["white","black"];
}
Cars.prototype.sayColor = function(){
  var outerColor = this.color; //保存一个副本到变量中
  return function(){
    return outerColor; //应用这个副本
  };
  outColor = null; //释放内存
};

var instance = new Cars();
console.log(instance.sayColor()())

稍微复杂一点的例子:

function inheritPrototype(subType,superType){
  var prototype = Object(superType.prototype);
  prototype.constructor = subType;
  subType.prototype = prototype;
}

function Cars(){
  this.name = "Benz";
  this.color = ["white","black"];
}
Cars.prototype.sayColor = function(){
  var outer = this;
  return function(){
    return outer.color;
  };
};

function Car(){
  Cars.call(this);
  this.number = [321,32];
}
inheritPrototype(Car,Cars);
Car.prototype.sayNumber = function(){
  var outer = this;
  return function(){
    return function(){
      return outer.number[outer.number.length - 1];
    }
  };
};

var instance = new Car();
console.log(instance.sayNumber()()());

首先,该例子组合使用了构造函数模式和原型模式创建Cars 对象,并用了寄生组合式继承模式来创建Car 对象并从Cars 对象获得属性和方法的继承;

其次,建立一个名为instance 的Car 对象的实例;instance 实例包含了sayColor 和sayNumber 两种方法;

最后,两种方法中,前者使用了一个闭包,后者使用了两个闭包,并对其this 进行修改使其能够访问到this.color 和this.number。

这里存在内存泄露问题,优化后的代码如下:

function inheritPrototype(subType,superType){
  var prototype = Object(superType.prototype);
  prototype.constructor = subType;
  subType.prototype = prototype;
}

function Cars(){
  this.name = "Benz";
  this.color = ["white","black"];
}
Cars.prototype.sayColor = function(){
  var outerColor = this.color; //这里
  return function(){
    return outerColor; //这里
  };
  this = null; //这里
};

function Car(){
  Cars.call(this);
  this.number = [321,32];
}
inheritPrototype(Car,Cars);
Car.prototype.sayNumber = function(){
  var outerNumber = this.number; //这里
  return function(){
    return function(){
      return outerNumber[outerNumber.length - 1]; //这里
    }
  };
  this = null; //这里
};

var instance = new Car();
console.log(instance.sayNumber()()());

以上就是为大家分享的解决方法,希望对大家的学习有所帮助。

(0)

相关推荐

  • 一分钟理解js闭包

    什么是闭包? 先看一段代码: function a(){ var n = 0; function inc() { n++; console.log(n); } inc(); inc(); } a(); //控制台输出1,再输出2 简单吧.再来看一段代码: function a(){ var n = 0; this.inc = function () { n++; console.log(n); }; } var c = new a(); c.inc(); //控制台输出1 c.inc(); //

  • 深入理解javascript函数参数与闭包

    最近在学习javascript的函数,函数是javascript的一等对象,想要学好javascript,就必须深刻理解函数.本人把学习的过程整理成文章,一是为了加深自己函数的理解,二是给读者提供学习的途径,避免走弯路.内容有些多,但都是笔者对于函数的总结. 1.函数参数 1.1:参数是什么 1.2:参数的省略 1.3:参数默认值 1.4:参数传递方式 1.5:同名参数 1.6:arguments对象 2.闭包 2.1:闭包定义 2.2:立即调用的函数表达式(IIFE, Immediately

  • JavaScript中闭包的写法和作用详解

    1.什么是闭包 闭包是有权访问另一个函数作用域的变量的函数. 简单的说,Javascript允许使用内部函数---即函数定义和函数表达式位于另一个函数的函数体内.而且,这些内部函数可以访问它们所在的外部函数中声明的所有局部变量.参数和声明的其他内部函数.当其中一个这样的内部函数在包含它们的外部函数之外被调用时,就会形成闭包. 2.变量的作用域 要理解闭包,首先要理解变量的作用域. 变量的作用域无非就是两种:全局变量和局部变量. Javascript语言的特殊之处,就在于函数内部可以直接读取全局变

  • 一道JS前端闭包面试题解析

    问题 代码A function fun(n,o){ console.log(o); return { fun:function(m){//[2] return fun(m,n);//[1] } } } var a=fun(0); a.fun(1); a.fun(2); a.fun(3); var b=fun(0).fun(1).fun(2).fun(3); var c=fun(0).fun(1); c.fun(2); c.fun(3); 求出程序输出 这是一个闭包测试题 转换为等价代码 retu

  • js闭包用法实例详解

    本文实例讲述了js闭包用法.分享给大家供大家参考,具体如下: 引言 在公司中需要写一个js脚本来进行网站的统计,实现类似百度统计或者站长统计的功能,在实现的过程中自己感觉写的代码还是可以的,因为之前的js代码都是这些写,但是在组长代码走查的时候却非常的不满意,因为我们在js中写的方法都是全局的方法,因为我们写的东西需要嵌入到别人的界面中,所以这些全局的东西很可能会和别人的东西重名从而引发错误,所以说组长就给我留下一句话:用js闭包包起来. 变量作用域 我们都非常的熟悉变量的作用域就分为:全局变量

  • 浅谈JavaScript for循环 闭包

    有个网友问了个问题,如下的html,为什么每次输出都是5,而不是点击每个p,就alert出对应的1,2,3,4,5. <html > <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>闭包演示</title> <script type="text/javascript&quo

  • 浅谈javascript的闭包

    关于闭包的解释 我们将作用域链描述为一个对象列表,不是绑定的栈.每次调用javascript函数的时候,都会为之创建一个新的对象来保存变量,把这个对象添那个加至作用域中,当函数返回时,就从作用域链中将这个绑定变量的对象删除,如果不存在嵌套函数,也没有其他引用指向这个绑定的对象,它就会被当垃圾回收掉, (function () { var val = null; var callback; setTimeout(function () { val = 1; callback(val) },1000

  • js实现为a标签添加事件的方法(使用闭包循环)

    本文实例讲述了js实现为a标签添加事件的方法.分享给大家供大家参考,具体如下: 以示例说明: 实现效果:循环为带有ml-praise样式类的a标签添加事件,并且在点击a标签后,相应的数量增加1. Html结构如下所示: <ul> <li><a href="javascript:;" class="ml-praise">数量:<span class="ding-num">100</span>

  • JavaScript利用闭包实现模块化

    利用闭包的强大威力,但从表面上看,它们似乎与回调无关.下面一起来研究其中最强大的一个:模块. function foo() { var something = "cool"; var another = [1, 2, 3]; function doSomething() { console.log( something ); } function doAnother() { console.log( another.join( " ! " ) ); } } 正如在这

  • 详谈JavaScript的闭包及应用

    闭包真的是学过一遍又一遍,Js博大精深,每次学习都感觉有新的收获.相信在大家封装前端插件时,闭包是必不可少的.闭包的真正好处我个人认为除了封装还是封装,能带个我们私有方法,和调用上的灵活方便,也会使你的代码对外的对象保持干净整洁. 进入正题 维基百科这样定义了JS闭包:在计算机科学中,闭包(英语:Closure),又称词法闭包(Lexical Closure)或函数闭包(function closures),是引用了自由变量的函数.这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的

  • javascript从作用域链谈闭包

    神马是闭包 关于闭包的概念,是婆说婆有理. 闭包是指有权访问另外一个函数作用域中的变量的函数 这概念有点绕,拆分一下.从概念上说,闭包有两个特点: 1.函数 2.能访问另外一个函数作用域中的变量 在ES 6之前,Javascript只有函数作用域的概念,没有块级作用域(但catch捕获的异常 只能在catch块中访问)的概念(IIFE可以创建局部作用域).每个函数作用域都是封闭的,即外部是访问不到函数作用域中的变量. function getName() { var name = "美女的名字&

随机推荐