闭包如何导致内存泄漏以及如何防止?
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>
代码执行后,将显示一个按钮,如下所示
按下按钮后,我们将获得以下输出
输出
避免泄漏