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

时间:2014-01-14 16:43:06

标签: javascript class object

我正试图弄清楚如何通过类方法删除对象。我希望能够创建一个具有destroy方法的类,该方法从内存中释放对象。到目前为止,我所做的研究尚无定论。我知道垃圾收集最终将处理对象,但我想要一种更明确的方法来摧毁它。这可能吗?

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

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

4 个答案:

答案 0 :(得分:37)

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

var obj = {};
obj.mypointer = null;
delete obj.mypointer;

2-关于delete关键字的重要一点是它实际上并没有销毁对象但是如果仅在删除对该对象的引用之后,内存中没有其他引用指向同一对象,该对象将被标记为收藏品。 delete关键字删除引用但不是GC实际对象。这意味着如果您有多个相同对象的引用,则在删除所有指向的引用之后将立即收集该对象。

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 = nulldelete storage.instance就足以删除对象的引用并允许GC清除它。不同之处在于,如果将其设置为null,则存储对象仍然具有名为instance的属性(值为null)。如果您delete 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;

哇太多了:)

答案 1 :(得分:16)

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

看到这将根据需要自动发生,明确回收内存的目的是什么?

答案 2 :(得分:3)

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

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 );
  }
}

答案 3 :(得分:0)

我发现从内存中删除类实例的方法:

Error: SelectFactory not connected to store!
    at SelectPlatformComponent.createSelect (webpack:///./node_modules/@ngxs/store/fesm5/ngxs-store.js?:1123:23)
    at SelectPlatformComponent.get [as platformList$] (webpack:///./node_modules/@ngxs/store/fesm5/ngxs-store.js?:1150:89)
    at Object.eval [as updateDirectives] (ng:///DynamicTestModule/SelectPlatformComponent.ngfactory.js:78:87)
    at Object.debugUpdateDirectives [as updateDirectives] (webpack:///./node_modules/@angular/core/fesm5/core.js?:11028:21)
    at checkAndUpdateView (webpack:///./node_modules/@angular/core/fesm5/core.js?:10425:14)
    at callViewAction (webpack:///./node_modules/@angular/core/fesm5/core.js?:10666:21)
    at execComponentViewsAction (webpack:///./node_modules/@angular/core/fesm5/core.js?:10608:13)
    at checkAndUpdateView (webpack:///./node_modules/@angular/core/fesm5/core.js?:10431:5)
    at callWithDebugContext (webpack:///./node_modules/@angular/core/fesm5/core.js?:11318:25)
    at Object.debugCheckAndUpdateView [as checkAndUpdateView] (webpack:///./node_modules/@angular/core/fesm5/core.js?:10996:12)