我一直在阅读js最佳做法和常见错误,我从https://www.toptal.com/javascript/10-most-common-javascript-mistakes
中看到了这段代码var theThing = null;
var replaceThing = function () {
var priorThing = theThing; // hold on to the prior thing
var unused = function () {
// 'unused' is the only place where 'priorThing' is referenced,
// but 'unused' never gets invoked
if (priorThing) {
console.log("hi");
}
};
theThing = {
longStr: new Array(1000000).join('*'), // create a 1MB object
someMethod: function () {
console.log(someMessage);
}
};
};
我尝试将此代码输入控制台并多次调用replaceThing()
并且确实如此,即使在GC之后,Chrome任务管理器中的内存使用率也会上升。
闭包unused
保留对priorThing的引用,从而使其不符合GC的条件。但是:
priorThing = theThing
时,unused
关闭中的引用是否也会更改为theThing
?unused
的执行完成时,变量replaceThing
是否应该超出范围?答案 0 :(得分:1)
是有内存泄漏。这是因为在Javascript中实现闭包的方式。每个函数对象都有一个链接到表示其词法范围的字典样式对象。 IF A VARIABLE IS USED IN ONE CLOSURE, IT ENDS UP IN THE LEXICAL SCOPE SHARED BY ALL OTHER CLOSURES IN THAT SCOPE
。在这种情况下,我们在同一范围内有两个闭包theThing
和unused
。在priorThing
中使用unused
,现在priorThing
是闭包中的变量,而unused
未被调用,则意味着priorThing
也在theThing
关闭的范围。因此priorThing
返回后,replaceThing
将不会收集垃圾。
1)执行priorThing = theThing
时,旧的theThing
值会存储到priorThing
,因此unused
指的是旧的theThing
而不是新创建的<{1}} < / p>