在理解涉及函数闭包时垃圾收集的方式时,我遇到了一些麻烦。例如,下面的JS代码使用闭包实现了一个加法器函数:
function adder() {
var sum = 0
return function(x) {
sum += x
return sum
}
}
function abc() {
var pos = adder()
for (i = 0; i < 10; i++) {
console.log(pos(i))
}
}
abc()
输出:
0
1
3
6
10
15
21
28
36
45 < / p>
每次调用函数pos
时,参数x
都会添加到sum
,并返回累计金额。我不明白的是,为什么sum
的值保留在函数adder
中?一旦内部函数返回(即pos
返回时),并不应该将sum的值收集到垃圾中。
相反,每次使用新值pos
调用x
时,前一次调用的总和会以某种方式保留在内存中。导致这种情况发生的背后发生了什么?
答案 0 :(得分:0)
这背后的魔力就是关闭: - )
每次调用一个函数时,都会为函数内部发生的所有内容(在大括号{ ... }
之间)留出一些内存(称为闭包)。此外,函数可以访问在其外部定义的所有内容。
因此,当您在第10行调用函数adder()
时,它会创建此闭包并在其中存储sum
。然后,adder()
返回一个函数。对于这个内部函数,sum
是全局函数,因此它可以在其体内访问和修改它,并且即使内部函数终止,值(存储在函数周围的闭包中)仍然存在。更重要的是,只要程序中存在对内部函数的引用,闭包就不会被垃圾收集,因为JavaScript知道内部函数可能与闭包相互作用。
总而言之,闭包对于内部函数是全局的,但对于外部世界是不可见的,这使得它们非常有用于在浏览器中封装JavaScript应用程序的各个部分。在node.js中,这个方面并不相关,因为模块概念已经执行了封装。