我正在创建一个将被重新创建多次的类,为了节省内存,我需要彻底删除它。基本上,如果可能的话,我需要访问其包含变量。
示例如下:
function example(){
this.id=0;
this.action=function(){alert('tost');}
this.close=function(){ delete this;}
}
var foo=new example();
我的问题是:
如何从 example 函数中访问 foo 变量,以便将其删除?
最佳答案
window.foo
将访问该全局变量。
this.close=function(){ delete window.foo; }
但是,我记得有 something fishy with global variables, delete and window ,所以您可能想要这样做,例如简单地使用 window.foo = null;
。
如果您想访问另一个函数中定义的变量,您需要读取 this SO question 的答案。
由于您想要的是允许垃圾收集器释放该对象,因此您需要确保没有对该对象的引用。这可能非常棘手(即不可能),因为操作对象的代码可以通过全局和局部变量以及属性对其进行多次引用。
您可以通过创建代理来访问该对象来防止直接引用该对象,不幸的是,javascript 不能很好地支持动态 getter 和 setter(也称为 catch-alls)(但在某些浏览器上您可能会实现它,see this SO question ) ,因此您无法轻松地将所有字段和方法(无论如何都只是字段)访问重定向到底层对象,特别是当底层对象动态添加和删除许多字段时(即 this.anewfield =新值
)。
这是一个简单的代理(代码为 jsfiddle.net ):
function heavyobject(destroyself, param1, param2) {
this.id=0;
this.action=function(){alert('tost ' + param1 + "," + param2);};
this.close=function(){ destroyself(); }
}
function proxy(param1, param2) {
object = null;
// overwrites object, the only reference to
// the heavyobject, with a null value.
destroyer = function() { object = null; };
object = new heavyobject(destroyer, param1, param2);
return function(fieldname, setvalue) {
if (object != null) {
if (arguments.length == 1)
return object[fieldname];
else
object[fieldname] = setvalue;
}
};
}
var foo = proxy('a', 'b');
alert(foo("action")); // get field action
foo("afield", "avalue"); // set field afield to value avalue.
foo("action")(); // call field action
foo("close")(); // call field close
alert(foo("action")); // get field action (should be 'undefined').
它的工作原理是返回一个函数,当使用单个参数调用时,获取包装对象上的一个字段,当使用两个参数调用时设置一个字段。它的工作原理是确保对重对象的唯一引用是 proxy
函数中的 object
局部变量。
heavyobject 中的代码必须永远泄漏this
(永远不返回它,永远不返回持有对var that = this
的引用的函数,切勿将其存储到另一个变量的字段中),否则可能会创建一些指向重对象的外部引用,从而阻止其删除。
如果 HeavyObject 的构造函数从构造函数内部(或构造函数调用的函数)调用 destroyself()
,则不会产生任何效果。
另一个更简单的代理,它将为您提供一个空对象,您可以在其上添加字段、读取字段和调用方法。我非常确定,有了这个,任何外部引用都无法逃脱。
代码(也在 jsfiddle.net 上):
function uniquelyReferencedObject() {
object = {};
f = function(field, value) {
if (object != null) {
if (arguments.length == 0)
object = null;
else if (arguments.length == 1)
return object[field];
else
object[field] = value;
}
};
f.destroy = function() { f(); }
f.getField = function(field) { return f(field); }
f.setField = function(field, value) { f(field, value); }
return f;
}
// Using function calls
o = uniquelyReferencedObject();
o("afield", "avalue");
alert(o("afield")); // "avalue"
o(); // destroy
alert(o("afield")); // undefined
// Using destroy, getField, setField
other = uniquelyReferencedObject();
other.setField("afield", "avalue");
alert(other.getField("afield")); // "avalue"
other.destroy();
alert(other.getField("afield")); // undefined
关于javascript - 从类函数中删除类变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11865171/