性能问答>闭包中外层函数未被直接引用的变量何时被 GC 回收>
1回复

闭包中外层函数未被直接引用的变量何时被 GC 回收



闭包例子如下:

function A() {
    var i = 1;
    var j = 2;
    return function(){
        return i;
    }();
}

var B = A();

在语句 return i 这一行设置断点,调试如下:

image.png
之前看过有关闭包的资料时知道由于函数 A 中的变量被引用,所以函数 A 不会被 GC 回收,那么这个不回收指的是整个函数 A 都不会被回收,还是被直接引用的部分不会被回收呢?
再举一例:

function A() {
    var i = {x : 1};
    var j = i;
    return function(){
        return j;
    }();
}

var B = A();

此时,i 被 j 引用,所以 i 和 j 指向同一个内存空间,但是断点调试时依然访问不到未被直接引用的变量 i:

image.png
最终的问题是:未被闭包直接引用的外层函数的变量在我设断点调试时到底有没有被 GC 回收呢?如果未被回收,为何我调试时访问不到呢?是因为作用域的问题吗?如果此时未被回收,那么该变量何时会被回收呢?
Firefox 和 Safari 调试时居然是可以访问到未引用的变量 j 的,截图如下:
1.Firefox:
image.png

2.Safari:
image.png
测试代码如下:

var v0 = 'i am at level 0';
var f1 = function () {
    var v1 = 'i am at level 1';
    var f2 = function (){
        var i = 1;
        var j = 2;
        var f3 = function (){
            console.log(i);
        }
        f3();
    }
    f2();
}
f1();

Chorme:
image.png

Firefox:

image.png

2566 阅读
请先登录,再评论

第二个closure “捕获”意思是,引用实际对象,也就closure中的aNumber实际上引到参数对象/值,所以改变传入的 param 引用不会影响 closure 的引用。因此只有 closure 没有引用时例子里则是addByEleven=null,才会释放.

1年前