It is necessary to notice that closured [[Scope]] in ECMAScript is the same object for several inner functions created in this parent context. It means that modifying the closured variable from one closure, affects the variable in another closure. - Dmitry Soshnikov
var theThing = null;
var replaceThing = function () {
var originalThing = theThing;
var unused = function () {
if (originalThing)
console.log("hi");
};
theThing = {
longStr: new Array(1000000).join('*'),
someMethod: function () {
console.log(someMessage);
}
};
};
setInterval(replaceThing, 1000);
现象:
泄漏原因:
在 replaceThing 激活时,NFE函数 unused 闭包了自由变量 originalThing。由于 someMethod 和 unused 共享同一个 [[Scopes]],因此 someMethod 也持有对 originalThing 的引用。在 theThing 的生命周期内,scope chain所持的闭包变量将无法被GC,而 originalThing 即指向本次循环前的 theTing 对象,故形成链状引用,不断累积。
DevTools的Heap Snapshot有以下两种视图可以分析闭包: