问题描述
我正在做一个正在经历范围/关闭的课程,并简要提及垃圾收集。在课程中提出了一个问题:
var sum =函数sumHndlr(x,y){
if( y!== undefined){
return x + y;
} else {
return function(y){
return x + y;
}
}
}
对我来说,对闭包的引用是当我们将函数到 sum
变量,但这并不意味着它会永远持续下去,或者我不理解js在编译器解析器等方面的执行方式吗?简单来说,垃圾回收是Javascript解释器/虚拟机的后台进程,它可以自动释放不再需要的对象的内存你的程序。
例如,既然你认为它是用于事件监听器的:当你从某个事件调度器中删除一个事件监听器(通常是一个函数)时,该计划的其他部分不会有任何参考事件监听器。因此,垃圾收集器可以并且将(在某个未知的时间)释放事件监听器所占用的内存。
由于闭包引用了一个作用域对象,所以按顺序如果我修改了一下你的例子:
$垃圾收集一个闭包,它不仅需要不需要引用,而且还需要作用域。
b $ b
/ * some stuff ... * /
function add10(a){
var adder = function(x){
返回函数(y){
return x + y;
}
}
var sum = adder(10); //创建一个闭包
return sum(a);
}
var thirty = add10(20);
/ *一些更多的东西... * /
<$> add10
被调用,即使程序继续执行更多的东西,垃圾收集器也可以释放与关闭关联的内存 sum
,因为它不再被引用,也不是与它关联的范围。
在这个例子中:
/ *有些东西.. 。* /
function add10AndGet20Adder(a){
var adders = function(x,y){
return [function(z){
return x + z;
},函数(z){
return y + z;
}]
}
var sums = adders(10,20); //创建一个闭包
return [sums [0](a),sums [1]];
}
var result = add10AndGet20Adder(50);
var sixty = result [0];
var add20 = result [1];
/ *一些更多的东西...... * /
更多的东西,总和[0]
不再被引用,但 add20
( sums [1]
)仍然引用了引用 x
和 y
,因此 sums
中的两个闭包中没有一个可以被垃圾收集器释放,直到 add20
为由程序引用。
我希望这可以使它更清晰,即使这些示例当然与真实代码无关。在实践中,只有在开发使用复杂闭包的长期程序(如单页应用程序或nodeJS服务器)时,才需要担心这一点。否则,关闭的内存使用情况不会成为问题。
这个SO问题提供了关于Javascript垃圾收集的更多细节:
I am doing a course which is going through scope/closures and briefly mentions garbage collection. During the course a question is posed:
var sum = function sumHndlr(x, y) {
if (y !== undefined) {
return x + y;
} else {
return function(y) {
return x + y;
}
}
}
So to me, the reference to the closure is when we assigned the function to the sum
variable, but won't that mean it lasts forever or am I not understanding the way the js will execute in regards to the compiler parser etc.?
Very briefly, garbage collection is a background process of the Javascript interpreter / virtual machine that automatically frees the memory of objects no longer needed by your program.
For example, since you think of it for event listeners: when you remove an event listener (a function usually) from some event dispatcher, it is likely that no other part of the program will have a reference to the event listener. Therefore, the garbage collector can and will (at some unknown time) free the memory that was taken by the event listener.
Since a closure references a scope object, in order to garbage-collect a closure it needs not only be unreferenced, but also the scope.
If I modify a bit your example:
/* some stuff ... */
function add10(a) {
var adder = function (x) {
return function(y) {
return x + y;
}
}
var sum = adder(10); //creates a closure
return sum(a);
}
var thirty = add10(20);
/* Some more stuff ... */
After add10
is called, even though the program continues to execute some more stuff, the garbage collector can free the memory associated to the closure sum
, because it is no longer referenced, nor is the scope associated to it.
Whereas in this example:
/* some stuff ... */
function add10AndGet20Adder(a) {
var adders = function (x, y) {
return [function(z) {
return x + z;
}, function(z) {
return y + z;
}]
}
var sums = adders(10, 20); //creates a closure
return [sums[0](a), sums[1]];
}
var result = add10AndGet20Adder(50);
var sixty = result[0];
var add20 = result[1];
/* Some more stuff ... */
When executing some more stuff, sums[0]
is no longer referenced, BUT add20
(sums[1]
) still has a reference to the scope that references x
andy
, therefore none of the two closures in sums
can be freed by the garbage collector, until add20
is referenced by the program.
I hope this makes it clearer, even though the examples are of course nowhere close to real code. In practice, you need to worry about this only if you develop a long-lived program (such as a single page application or nodeJS server) with complicated usage of closures. Otherwise, the memory usage of the closures is unlikely to be a problem.
This SO question gives more details about Javascript garbage collection: What is JavaScript garbage collection?
这篇关于这个scope / closure是什么时候在javaScript中被垃圾收集的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!