Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/backbone.js/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_Class_Object - Fatal编程技术网

JavaScript:通过类方法创建和销毁类实例

JavaScript:通过类方法创建和销毁类实例,javascript,class,object,Javascript,Class,Object,我试图弄清楚如何通过类方法删除对象。我希望能够创建一个具有destroy方法的类,该方法可以从内存中释放对象。到目前为止,我所做的研究还没有得出结论。我知道垃圾收集最终会处理这个对象,但我希望有一个更明确的方法来销毁它。这可能吗 // class constructor var class = function () { this.destroy = function () {}; }; // instance var instance = new class(); instance

我试图弄清楚如何通过类方法删除对象。我希望能够创建一个具有destroy方法的类,该方法可以从内存中释放对象。到目前为止,我所做的研究还没有得出结论。我知道垃圾收集最终会处理这个对象,但我希望有一个更明确的方法来销毁它。这可能吗

// class constructor
var class = function () {
     this.destroy = function () {};
};

// instance
var instance = new class();
instance.destroy();
console.log(instance); // should be null or undefined

否。JavaScript被自动垃圾收集;只有当GC决定运行并且对象符合收集条件时,才会回收对象的内存


鉴于这将根据需要自动发生,显式回收内存的目的是什么?

您只能手动删除对象的属性。因此:

var container = {};

container.instance = new class();

delete container.instance;
但是,这在任何其他指针上都不起作用。因此:

var container = {};

container.instance = new class();

var pointer = container.instance;

delete pointer; // false ( ie attempt to delete failed )
此外:

delete container.instance; // true ( ie attempt to delete succeeded, but... )

pointer; // class { destroy: function(){} }
所以在实践中,删除只对删除对象属性本身有用,而不是从内存中删除它们指向的代码的可靠方法

手动指定的
destroy
方法可以解除任何事件侦听器的绑定。比如:

function class(){
  this.properties = { /**/ }

  function handler(){ /**/ }

  something.addEventListener( 'event', handler, false );

  this.destroy = function(){
    something.removeEventListener( 'event', handler );
  }
}

1-没有办法在javascript中实际销毁对象,但使用
delete
,我们可以从对象中删除引用:

var obj = {};
obj.mypointer = null;
delete obj.mypointer;
2-关于
delete
关键字的重要一点是,它实际上不会破坏该对象,但如果仅在删除对该对象的引用后,内存中没有指向同一对象的其他引用,则该对象将被标记为可收集。
delete
关键字删除引用,但不删除实际对象。这意味着,如果同一对象有多个引用,则在删除所有指向的引用后,将立即收集该对象

3-当我们想要确保不会留下任何内存泄漏时,还有一些技巧和解决方法可以帮助我们解决问题。例如,如果有一个由多个对象组成的数组,而没有对这些对象的任何其他指向引用,那么如果重新创建该数组,所有这些对象都将被杀死。例如,如果您有
var-array=[{},{}]
array=[]
那样重写数组的值,将删除对数组中两个对象的引用,并且这两个对象将被标记为可收集

4-对于您的解决方案,最简单的方法就是:

var storage = {};
storage.instance = new Class();
//since 'storage.instance' is your only reference to the object, whenever you wanted to destroy do this:
storage.instance = null;
// OR
delete storage.instance;
如上所述,设置
storage.instance=null
delete storage.instance
都足以删除对对象的引用,并允许GC清除它。不同之处在于,如果将其设置为
null
,则存储对象仍有一个名为instance的属性(值为null)。如果
删除storage.instance
,则存储对象不再具有名为instance的属性

那么销毁方法呢???

这里的矛盾之处在于,如果您在destroy函数中使用
instance.destroy
,则无法访问实际的
instance
指针,并且它不允许您删除它

唯一的方法是将引用传递给destroy函数,然后将其删除:

// Class constructor
var Class = function () {
     this.destroy = function (baseObject, refName) {
         delete baseObject[refName];
     };
};

// instanciate
var storage = {};
storage.instance = new Class();
storage.instance.destroy(object, "instance");
console.log(storage.instance); // now it is undefined
但是如果我是你,我只会坚持第一个解决方案并删除对象,如下所示:

storage.instance = null;
// OR
delete storage.instance;

哇,太多了:)

这类问题的可能重复似乎来自对对象实例如何生存和死亡的误解。这根本不是JS的工作方式,但这并不意味着它是一种限制。这意味着事情需要以不同的方式进行。那么您真正的目标是什么呢?我的目标是快速删除对象,包括事件处理程序和创建对象后创建的任何内容@尼克:看看我的答案,我想你会得到你想要的一切。我不是SO的常客,所以这么晚才遇到。我经常看到人们试图定义类的范围,但却用document.head.appendChild()将其加载到文档中。这将进行注册,并且eval()-即使eval.call({},js)将使用窗口范围查找类。相反,不要将其添加到文档中(如果是),而是使用类似eval.call({},'class myclass{}(function(){return new myclass()})(')的方法来评估整个类。这不应该使用窗口,您可以随时替换MyClass。我想快速删除创建对象时创建的事件处理程序、引用等。@user699242:再说一遍,为什么?如果对象中没有一个引用了该内容,那么回收该对象也将允许回收该内容。除了“丢失”对对象的所有引用之外,不需要执行任何操作。为什么要手动执行此操作?我想“失去对对象的所有引用”对我来说是不明确的。什么时候会这样?对不起,这总是让我困惑。换句话说,我需要做些什么来“放松参考资料”吗。例如,将指针设置为null或…枚举的可能性太多,但通常“将该对象设置为
null
”会起作用。但是,这是您应该更好地处理的事情,因为它可以决定内存泄漏是否会导致崩溃。你真的必须试着那样泄密,但是……这不是=void 0;左手作业无效?你完全正确。这也是一个非常愚蠢的想法,因为它所能做的就是由于缺少指针而导致错误。@vsync如果它没有附加到任何对象或变量,那么它将在运行完任何代码后被收集。例如,如果您执行
(new SomeObject).doSomething
,则在执行
doSomething
后,将对其进行收集。如果对象有一个
setTimeout
调用或任何其他触发异步逻辑的东西,那么在其他任务完成之前,不会收集某个对象(除非这些任务不包含对