我正在创建一个类,它将被多次重新创建,为了节省内存,我需要彻底删除它。基本上,如果可能的话,我需要访问它的包含变量。
下面是一个例子:
function example(){
this.id=0;
this.action=function(){alert('tost');}
this.close=function(){ delete this;}
}
var foo=new example();
- 我的问题是**
如何从example函数中访问foo变量以便删除它?
我正在创建一个类,它将被多次重新创建,为了节省内存,我需要彻底删除它。基本上,如果可能的话,我需要访问它的包含变量。
下面是一个例子:
function example(){
this.id=0;
this.action=function(){alert('tost');}
this.close=function(){ delete this;}
}
var foo=new example();
如何从example函数中访问foo变量以便删除它?
3条答案
按热度按时间0qx6xfy61#
window.foo
将访问该全局变量。但是,我记得有something fishy with global variables, delete and window,所以您可能想用其他方法,例如简单地使用
window.foo = null;
。如果你想访问另一个函数中定义的变量,你需要读取this SO question的答案。
因为你想要的是允许垃圾收集器释放那个对象,所以你需要确保没有对那个对象的引用,这可能是相当棘手的(也就是不可能的),因为操作对象的代码可以通过全局和局部变量以及属性对它进行多次引用。
您可以通过创建一个代理来访问对象,从而防止直接引用对象,不幸的是javascript不支持动态getter和setter(也称为全捕集)非常好(在某些浏览器上,您可能会实现它,see this SO question),因此您不能轻松地重定向所有字段和方法(无论如何都只是字段)访问底层对象,特别是在底层对象动态添加和删除了许多字段的情况下(即
this.anewfield = anewvalue
)。下面是一个简单的代理(代码在jsfiddle.net上):
它的工作原理是返回一个函数,当用一个参数调用时,获取 Package 对象上的一个字段,当用两个参数调用时,设置一个字段;它的工作原理是确保heavyobject的唯一引用是
proxy
函数中的object
局部变量。heavyobject中的代码必须 * 永不 * 泄漏
this
(永不返回它,永不返回一个引用var that = this
的函数,永不将它存储到另一个变量的字段中),否则可能会创建一些指向heavyobject的外部引用,从而阻止它被删除。如果heavyobject的构造函数从构造函数内部(或从构造函数调用的函数)调用
destroyself()
,则不会有任何效果。另一个更简单的代理,它会给予你一个空的对象,你可以在上面添加字段,读取字段,和调用方法。我很肯定,使用这个代理,没有外部引用可以逃脱。
代码(也在jsfiddle.net上):
nnsrf1az2#
事实是,您不能删除Javascript中的对象。
然后你使用delete运算符,它只接受某个对象的属性,所以,当你使用delete时,通常你必须传递给它类似
obj.p
的东西,然后你只传递一个变量名,实际上这意味着'全局对象的属性',而delete p
与delete window.p
相同。不确定delete this
内部发生了什么,但结果浏览器就跳过它。现在,我们用
delete
实际上删除了什么?我们删除了一个对象的引用。这意味着对象本身仍然在内存中。为了消除它,你必须删除所有对具体对象的引用。所有引用-从其他对象,从闭包,从事件处理程序,链接数据,所有这些。但是对象本身没有关于所有这些引用的信息。因此无法从对象本身删除对象。请看以下代码:为了从内存中删除obj,你必须删除
someAnother.myObjRef
和someAnoterAnother.secondRef
。你只能从program的一部分中删除它们。如果我们可以有任意数量的引用,我们如何删除一些东西呢?有一些方法可以解决这个问题:
obj.x=1
更改为obj.val('x',1)
。此外,这一点不太明显,事实上你把所有对obj的引用都改成了对proxy的引用。proxy将永远保留在内存中而不是object。根据对象的大小,对象的数量和实现,这可以给你带来一些好处,或者甚至使事情变得更糟。例如,如果你的对象的大小接近proxy本身的大小-你将没有任何价值。obj.close()
--你已经知道了删除它所需要的一切。只是代替obj.close()
来杀死对它的引用。一般来说--把这个引用改为另一个东西:但使用这种方法时,你必须记住引用可能出现在很难理解的地方。2例如:
引用存储在
result
函数的闭包中,当您在某处引用result
时,obj将保留在内存中。72qzrwbm3#
这里有一个链接,指向有关JavaScript删除操作符的一些非常详细的信息。
http://perfectionkills.com/understanding-delete/