闭包如何导致内存泄漏以及如何防止?

javascriptobject oriented programmingprogramming

闭包

闭包是 JavaScript 的优势之一。JavaScript 允许嵌套函数(函数内的函数)访问父函数的变量。内部函数访问外部函数变量的过程称为闭包。当声明的变量自动可供内部嵌套函数使用并驻留在内存中时,就会发生内存泄漏,尽管内部嵌套函数中没有引用该变量。

在下面的例子中,"childFunction"是在外部函数"parentFunction"中定义的内部函数。当调用"parentFunction"时带有参数"outer val",外部变量 a 被赋予"outer val"的值。该函数返回指向内部函数"childFunction"的指针,该指针包含在变量"val"中。

即使外部函数已返回,外部函数的局部变量 a 仍将存在。在 javascript 中,调用 parentFunction 时,会创建一个具有属性"a"的作用域对象。此属性包含 arg1 的值,也称为"outer val"。同样,当 parentFunction 返回时,它将返回内部函数(childFunction),该函数包含在变量 val 中。

由于内部函数保存对外部函数变量的引用,因此具有属性"a"的作用域对象不会被垃圾回收。 

示例  

<html>
<body>
<script>
   window.onload= function parentFunction(arg1) {
      var a = arg1;
      return function childFunction (arg2)
   {
      alert( a +" "+ arg2);
   };
   };
   var val = parentFunction("outer val");
   val("inner val");
</script>
</body>
</html>

避免内存泄漏

添加另一个函数

通过添加另一个函数,将有两个内部函数。由于有两个内部函数,因此没有函数可以通过完全停止闭包来引用外部函数的变量。

当没有闭包时,内存泄漏的可能性会更小。

示例

<html>
<body>
<script>
   window.onload=function parentFunction(){
      var Obj1 = function childFunction1()
      {
         document.write("避免泄漏");
      };
   (function childFunction2(){
      var obj2 = document.getElementById("closure");
      obj2.onclick=Obj1
      })();
   };
</script>
<input type = "button" id="closure" value ="Click Here>
</body>
</html>

代码执行后,将显示一个按钮,如下所示

按下按钮后,我们将获得以下输出

输出

避免泄漏

相关文章