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;