Bootstrap

js闭包和内存泄漏

闭包的概念

闭包是指有权访问另一个函数作用域中的变量的函数。创建闭包的方式,就是在一个函数内部返回一个匿名函数。

function test() {
    var num = 0;
    return function () {
        num++
        console.log(num);
    };
}
test()();//1
内存泄漏

内部函数被外部函数包含时,内部函数会将外部函数的局部活动对象添加到自己的作用域链中。而由于内部匿名函数的作用域链在引用外部包含函数的活动对象 ,即使test执行完毕了,它的活动对象还是不会被销毁!

根据垃圾回收机制,被另一个作用域引用的变量不会被回收。

所以,除非内部的匿名函数解除对活动变量的引用(解除对匿名函数的引用),才可以释放内存。

function test() {
    var num = 0;
    return function () {
        num++
        console.log(num); // 这样会导致闭包引用外层的num,当执行完num后,num无法释放
    };
}
// 改为
function test() {
    var num = {
		val: 0
	};
    return function () {
        num.val++
        console.log(num.val);
    };
    num = null // 将num设置为null之后,num.val无法取到,则垃圾回收机制会回收掉num
}
结论

许多人对闭包和内存泄露的关系有误解,认为闭包一定会引起内存泄漏,其实是不对的,我来谈谈我对他们关系的理解。闭包和内存泄露有关系的地方是,使用闭包的同时比较容易形成循环引用,如果闭包的作用域链中保存着一些DOM节点,这时候就有可能造成内存泄露。这主要是程序员容易引起的bug,不是浏览器的问题。
如果要解决循环引用带来的内存泄露问题,我们只需要把循环引用中的变量设为null即可。将变量设置为null意味着切断变量与它此前引用的值之间的连接。当垃圾收集器下次运行时,就会删除这些值并回收它们占用的内存。

;