对象成员

时间:2017-02-26 21:59:37

标签: javascript object closures

我确信之前已经问过,但我找不到它。

以下示例Javascript闭包的内存使用情况是什么:

var f = (function(sz){
    var obj = {
        x : sz,
        y : new Array(sz),
    };

    var _x = obj.x;

    return function() {
        return obj.x;
    };
})(1000000);

应该为结果闭包保留多少obj?将所有obj保留在内存中,还是仅保留obj.x的内容?

我应该说我尝试(像新手一样)在Google Chrome中使用堆分析器。在关闭之前,总堆大小为5.3MB。关闭后,当我将obj.y数组大小(sz)设置为1,000,000时,总堆大小为13.2MB,f保留8MB。这表明obj.y仍留在记忆中。当我将sz更改为10,000,000时,堆大小为81.9MB,f保持健康的80MB。与剩余obj.y一致。但是当我使用100,000 {的sz时,配置文件显示堆大小仅为5.6M,f保留0.5MB。这告诉我obj.y被垃圾带走了。并且在任何时候,f()都会返回正确的值,因此假设闭包按预期工作。

所以问题仍然存在,上述关闭内存中的内容是什么?显然,我知道它可以是什么,但它应该是什么?

1 个答案:

答案 0 :(得分:2)

我认为你可以通过在means/1行的调试器中放置一个断点来判断闭包中是否包含完整的对象,然后添加一行来执行f所持有的函数来触发它: / p>

return obj.x;

在该断点处,您可以查询对象f();,您将看到它确实是整个对象。所以我想说,是的,所有的obj都是基于那个闭包。

我使用节点并使用具有相同结果的Chrome浏览器对此进行了测试。也许其他javascript引擎优化了这一点并且表现不同。

关于垃圾收集,我想说对垃圾收集器所做的事情进行测量是很有挑战性的,因为当这种情况发生时是相当不可预测的并且取决于很多因素。

编辑 - 附加信息

我想更清楚地说明闭包的内容。在JavaScript中,垃圾收集只会发生在无法访问的事物(变量,函数......)上。只要有东西可以到达,它就不会被垃圾收集。

要查看此函数包含的闭包,我们可以在控制台中使用obj命令。

以下是控制台会话示例(Chrome浏览器控制台):

console.dir()

现在,感兴趣的是在> var f = (function(sz){ var obj = { x : sz, y : new Array(sz), }; var _x = obj.x; return function() { return obj.x; }; })(1000000); <- undefined > console.dir(f) function anonymous() arguments: null caller: null length: 0 name: "" prototype: Object __proto__: () [[FunctionLocation]]: VM24461:9 [[Scopes]]: Scopes[2] 0: Closure obj: Object x: 1000000 y: Array[1000000] __proto__: Object 1: Global <- undefined 下我们看到这个函数的闭包,并且该闭包是[[Scopes]]。这意味着obj是可达的,因此不能进行垃圾回收。这也意味着obj.y可以访问(通过obj),因此也不能进行垃圾收集。

希望这有助于进一步明确。 obj非常便于查看更多关闭。