it-swarm.com.de

JavaScript: Klasseninstanz mit Klassenmethode erstellen und zerstören

Ich versuche herauszufinden, wie ein Objekt durch eine Klassenmethode gelöscht wird. Ich möchte in der Lage sein, eine Klasse mit einer Zerstörungsmethode zu erstellen, die das Objekt aus dem Speicher freigibt. Bisher war meine Forschung nicht schlüssig. Ich verstehe, dass die Müllsammlung sich letztendlich um das Objekt kümmern wird, aber ich möchte einen definitiveren Weg, es zu zerstören. Ist das möglich?

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

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

Nein. JavaScript wird automatisch Müll gesammelt. Der Speicher des Objekts wird nur zurückgefordert, wenn der GC die Ausführung beschließt und das Objekt für die Sammlung in Frage kommt.

Da dies bei Bedarf automatisch geschieht, was wäre der Zweck, den Speicher explizit wiederzugewinnen?

14
Jon

1- Es gibt keine Möglichkeit, ein Objekt in Javascript tatsächlich zu zerstören, aber mit delete könnten wir eine Referenz von einem Objekt entfernen:

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

2- Der wichtige Punkt beim Schlüsselwort delete besteht darin, dass das Objekt nicht wirklich zerstört wird, ABER wenn nur die Referenz auf das Objekt gelöscht wird und im Speicher kein anderer Verweis mehr vorhanden ist, der auf dasselbe Objekt verweist, wird dieses Objekt als gekennzeichnet Sammlerstück. Das delete-Schlüsselwort löscht den Verweis, GC-Objekt jedoch nicht. Wenn Sie also mehrere Verweise auf dasselbe Objekt haben, wird das Objekt sofort nach dem Löschen aller Verweise gesammelt.

Es gibt auch einige Tricks und Problemumgehungen, die uns helfen könnten, wenn wir sicherstellen möchten, dass wir keine Speicherlecks hinterlassen. Wenn Sie beispielsweise ein Array mit mehreren Objekten haben, ohne einen anderen spitzen Verweis auf diese Objekte, wenn Sie das Array neu erstellen, werden alle diese Objekte abgebrochen. Wenn Sie zum Beispiel var array = [{}, {}] den Wert des Arrays wie array = [] überschreiben, werden die Verweise auf die beiden Objekte innerhalb des Arrays entfernt und diese beiden Objekte werden als sammelbar markiert.

4- Für Ihre Lösung ist der einfachste Weg dieser:

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;

Wie bereits erwähnt, würde entweder die Einstellung storage.instance = null oder delete storage.instance ausreichen, um den Verweis auf das Objekt zu entfernen und durch den GC bereinigen zu können. Der Unterschied besteht darin, dass das Speicherobjekt, wenn Sie es auf null setzen, noch eine Eigenschaft namens Instanz (mit dem Wert null) besitzt. Wenn Sie delete storage.instance haben, hat das Speicherobjekt keine Eigenschaft mit dem Namen Instanz mehr.

und WAS ungefähr zerstören Methode ??

der paradoxe Punkt hier ist, wenn Sie instance.destroy in der Funktion destroy verwenden, haben Sie keinen Zugriff auf den tatsächlichen instance-Zeiger, und Sie können ihn nicht löschen.

Die einzige Möglichkeit ist, die Referenz an die Zerstörungsfunktion zu übergeben und sie dann zu löschen:

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

ABERWenn ich Sie wäre, würde ich einfach bei der ersten Lösung bleiben und das Objekt wie folgt löschen:

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

WOW es war zu viel :)

34
Mehran Hatami

Sie können Eigenschaften von Objekten nur manuell löschen. Somit:

var container = {};

container.instance = new class();

delete container.instance;

Dies funktioniert jedoch nicht für andere Zeiger. Deshalb:

var container = {};

container.instance = new class();

var pointer = container.instance;

delete pointer; // false ( ie attempt to delete failed )

Außerdem:

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

pointer; // class { destroy: function(){} }

In der Praxis ist das Löschen daher nur nützlich, um Objekteigenschaften selbst zu entfernen, und es ist keine zuverlässige Methode zum Entfernen des Codes, auf den sie verweisen, aus dem Speicher.

Eine manuell angegebene destroy-Methode kann die Ereignis-Listener aufheben. So etwas wie:

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

  function handler(){ /**/ }

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

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

Die Methode, die ich gefunden habe, um meine Klasseninstanzen aus dem Speicher zu entfernen:

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