Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 垃圾收集器:删除对具有对另一个对象的引用的对象的引用_Javascript - Fatal编程技术网

Javascript 垃圾收集器:删除对具有对另一个对象的引用的对象的引用

Javascript 垃圾收集器:删除对具有对另一个对象的引用的对象的引用,javascript,Javascript,据我所知,JS垃圾收集器删除不再被引用的对象。假设我删除了对一个对象的引用,而该对象具有一个属性,该属性是对另一个对象的引用。两个对象都将被删除吗 e、 g var objectA = { prop1: "property", prop2: "property" } var objectB = { refToA: objectA } // Remove reference to objectA delete objectA; // Remove reference

据我所知,JS垃圾收集器删除不再被引用的对象。假设我删除了对一个对象的引用,而该对象具有一个属性,该属性是对另一个对象的引用。两个对象都将被删除吗

e、 g

var objectA = {
    prop1: "property",
    prop2: "property"
}

var objectB = {
    refToA: objectA
}

// Remove reference to objectA
delete objectA;

// Remove reference to objectB
delete objectB

这两个对象现在都从内存中完全删除了吗

简短回答:是的。未在任何位置引用的对象将从内存中完全删除,而不管该对象属性引用了什么

在您的代码片段中,事情相当简单,但当您开始使用闭包时,mem管理可能会变得棘手:

var objA = (function()
{
    var objAb = {who:'An object literal in closure scope',globalReference:'None!'};
    return {who:'Return value, is an object literal that references a closure object'.
            closureObj : objAb};
})();
var objB = {who:'some object',objAb:{who:'object literal, referenced by objB.objAb'}};
var objBAb = objB.objAb;//reference to obj literal, referenced by objB.objAb
var objAb = objA.closureObj;//reference to obj literal, referenced by objA.closureObj, which in turn references the closure object literal

delete objB.objAb;
console.log(objBAb);//<-- the object literal that was declared as a property of objB still exists
delete objAb;//<-- this reference is gone, but the closure obj still exists 
console.log(objA.closureObj);//<-- object is there
在上一个示例中,最后一个delete语句将足以GC闭包对象文本。但是,现在objA有两种方法(引用函数对象的属性)。这些方法仍然引用闭包对象,并且仍然被
objA
引用,因此
closureObj
还不能被GC'ed。所以,这就是事情变得棘手的地方:

delete objA.closureReference;
delete objA.reset;
delete objA.getClosureReference;
我们已经删除了所有可以链接回
closureObj
的属性,所以它会被GC'ed,对吗--嗯,不完全是。Chrome的V8确实释放了内存,但我听说Opera中也有类似的代码导致泄漏,而且IE可能不会擅长回收内存

此外,我们还使用
getClosureReference
有效地创建了一个getter方法,因此在现实生活中,这种情况很可能发生:

//do stuff
delete objA.closureReference;
var objB = objA.getClosureReference();//<-- created new reference to closure object
//do some more stuff
delete objA.reset;
delete objA.getClosureReference;
//做事
删除objA.closureference;

var objB=objA.getClosureReference()//全局变量objectA和属性refToA都引用同一个对象。一旦两个引用都消失,两个引用的对象都将消失。
//do stuff
delete objA.closureReference;
var objB = objA.getClosureReference();//<-- created new reference to closure object
//do some more stuff
delete objA.reset;
delete objA.getClosureReference;