【发布时间】:2019-12-11 01:29:28
【问题描述】:
考虑以下示例:
function makeFunction() {
let x = 3;
let s = "giant string, 100 MB in size";
return () => { console.log(x); };
}
// Are both x and s held in memory here
// or only x, because only x was referred to by the closure returned
// from makeFunction?
let made = makeFunction();
// Suppose there are no further usages of makeFunction after this point
// Let's assume there's a thorough GC run here
// Is s from makeFunction still around here, even though made doesn't use it?
made();
因此,如果我只关闭父词法环境中的一个变量,该变量是否保留,或者其词法环境中的每个同级变量也保留?
另外,如果 makeFunction 本身嵌套在另一个外部函数中,即使 makeFunction 和 makeFunction 的返回值都没有引用该外部词法环境中的任何内容,是否会保留该外部词法环境?
我问的是性能原因 - 闭包是保留一堆东西还是只保留它们直接引用的东西?这会影响内存使用和资源使用(例如打开的连接、句柄等)。
这主要是在 NodeJS 上下文中,但也可以在浏览器中应用。
【问题讨论】:
-
当然,如果您使用
eval或一些花哨的arguments调用,则必须保留整个词法范围,因此默认情况下闭包不能仅保留对明确引用的内容的引用.此外,如果您访问任何非常量全局变量,这些全局变量稍后可能是eval(或更改为eval)。但是,在某些情况下,个别引擎可能会优化掉引用(如果没有使用有趣的东西)。我也很想知道这个问题的答案。 -
这取决于浏览器和实现。 Afaik 大多数现代浏览器都试图不保留它。但不能保证。
-
您有什么性能原因要问?函数执行后,该范围内所有未引用的内存都应该被释放。垃圾回收是 JavaScript 的一个内部特性;使用这种语言进行开发时,您实际上不必考虑它。您可以在此处阅读有关内存管理的信息:developer.mozilla.org/en-US/docs/Web/JavaScript/…
-
尝试使用
console.dir(made);并深入了解[[Closure]]属性以查看它保留的内容。
标签: javascript node.js v8