所有
我是javascript管理的新手,当我尝试理解GC如何处理闭包时,我运行了一个例子:
function addN(n){
var title = "ADD "+n;
return function adder(who){
return who+n;
}
}
var add3 = addN(3);
var result = add3(10);
我想知道addN完成为add3构建关闭后, title
仍然留在内存中,或者它只是n
吗?
另一个例子是:
var globaltable = []
function addNarray(narray){
// narray is an string array
var titles = narray.slice(0);
globaltable = globaltable.concat(titles);
return function adder(who){
return narray.join(" - ");
}
}
在此示例中,会title
获得GCed 吗?
我也想知道如果那个叙事是一个像{id:0, name:"idname"}
这样的对象数组,那么答案是否相同?
如果有人知道答案,请分享一个想法,并且一个chrome devtool方式证明将非常感激,或者从内存使用角度解释一下
由于
答案 0 :(得分:4)
您可以使用console.dir(add3);
查看闭包的构造。展开[[Scopes]]
属性,然后展开0: Closure
对象,您将只看到:
n: 3
闭包不会将title
的值保存在任何地方。
在第二个示例中,titles
变量仍然是垃圾回收。当你这样做时:
var titles = narray.slice(0);
globaltable = globaltable.concat(titles);
发生以下情况:
narray
的副本由slice()
创建,并存储在本地变量titles
中。globaltable
内容后跟titles
内容的新数组。globaltable
。此时globaltable
的旧值变为垃圾。当addNarray()
返回时,titles
的值变为垃圾,因为adder()
中的闭包没有任何对它的引用。
titles
中的字符串不会变成垃圾,因为它们仍在globalarray
中引用。并且narray
不会变成垃圾,因为它是adder
闭包中的引用。
基本上,闭包应仅保持对返回函数中某处提到的变量的引用。外部范围中的其他变量不需要保存。
垃圾收集的基本原理很简单:如果无法访问一段数据,可以将其收集为垃圾。实施中有时会出现错误,但作为一般规则,您可以认为这是真的。