JavaScript: создание и уничтожение экземпляра класса методом класса

Я пытаюсь выяснить, как удалить объект с помощью метода класса. Я хотел бы иметь возможность создать класс, который имеет метод destroy, который освобождает объект из памяти. До сих пор исследования, которые я сделал, были неубедительными. Я понимаю, что сбор мусора в конечном итоге позаботится об объекте, но я бы хотел более решительный способ его уничтожить. Это возможно?

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

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

Ответы

Ответ 1

Нет. JavaScript автоматически собирает мусор; память объекта будет восстановлена только в том случае, если GC решит запустить, и объект имеет право на сбор.

Видя, как это будет происходить автоматически, как требуется, какова была бы цель для исправления памяти явно?

Ответ 2

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). Если вы delete storage.instance у объекта хранения больше не будет свойства с именем instance.

а что насчет уничтожить методом??

парадоксальным моментом здесь является то, что если вы используете instance.destroy в функции уничтожения, у вас нет доступа к фактическому указателю instance, и он не позволит вам удалить его.

Единственный способ - передать ссылку на функцию уничтожения, а затем удалить ее:

// 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;

WOW это было слишком много :)

Ответ 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 );
  }
}

Ответ 4

Метод, который я нашел, чтобы удалить экземпляры класса из памяти:

var instance = new Class();
instance.__proto__ = null;
instance = null;
delete instance;