web-dev-qa-db-fra.com

JavaScript: créer et détruire une instance de classe à l'aide de la méthode de classe

J'essaie de comprendre comment supprimer un objet à l'aide d'une méthode de classe. Je voudrais pouvoir créer une classe qui a une méthode de destruction qui libère l'objet de la mémoire. Jusqu'à présent, les recherches que j'ai effectuées n'ont pas été concluantes. Je comprends que le ramassage des ordures finira par prendre soin de l'objet, mais j'aimerais un moyen plus définitif de le détruire. Est-ce possible?

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

Non, JavaScript est automatiquement récupéré. la mémoire de l'objet ne sera récupérée que si le GC décide de s'exécuter et que l'objet est éligible pour la collecte.

Étant donné que cela se produira automatiquement, le cas échéant, à quoi servirait de récupérer explicitement la mémoire?

14
Jon

1- Il n'y a aucun moyen de détruire un objet en javascript, mais en utilisant delete, nous pourrions supprimer une référence à un objet:

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

2- Le point important sur le mot clé delete est qu'il ne détruit pas l'objet MAIS si seulement après avoir supprimé cette référence à l'objet, il ne reste aucune autre référence dans la mémoire pointée sur le même objet, cet objet est marqué comme à collectionner. Le mot clé delete supprime la référence mais ne GC pas l'objet réel. cela signifie que si vous avez plusieurs références d'un même objet, l'objet sera collecté juste après la suppression de toutes les références pointées.

3- Il existe également des astuces et des solutions de contournement qui pourraient nous aider, lorsque nous voulons nous assurer de ne laisser aucune fuite de mémoire. Par exemple, si vous avez un tableau composé de plusieurs objets, sans autre référence pointée à ces objets, si vous le recréez, tous ces objets seraient tués. Par exemple, si vous avez var array = [{}, {}] surchargé la valeur du tableau, array = [] enlèverait les références aux deux objets à l'intérieur du tableau et ces deux objets seraient marqués comme pouvant être collectionnés.

4- pour votre solution le moyen le plus simple est ceci:

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;

Comme mentionné ci-dessus, le réglage de storage.instance = null ou delete storage.instance suffirait pour supprimer la référence à l'objet et lui permettre d'être nettoyé par le GC. La différence est que si vous le définissez sur null, l'objet de stockage a toujours une propriété appelée instance (avec la valeur null). Si vous delete storage.instance, alors l'objet de stockage n'a plus de propriété nommée instance.

et QU'EN EST-IL DE détruire la méthode ??

le point paradoxal ici est que si vous utilisez instance.destroy dans la fonction de destruction, vous n’avez pas accès au pointeur instance, et il ne vous laissera pas le supprimer.

Le seul moyen est de passer la référence à la fonction destroy, puis de la supprimer:

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

MAISsi j'étais vous, je me contenterais de la première solution et supprimerais l'objet comme ceci:

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

WOW c'était trop :)

34
Mehran Hatami

Vous pouvez uniquement supprimer manuellement les propriétés des objets. Ainsi:

var container = {};

container.instance = new class();

delete container.instance;

Cependant, cela ne fonctionnera sur aucun autre pointeur. Donc:

var container = {};

container.instance = new class();

var pointer = container.instance;

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

En outre:

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

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

Ainsi, en pratique, la suppression n'est utile que pour supprimer les propriétés d'objet elles-mêmes et n'est pas une méthode fiable pour supprimer le code qu'ils pointent de la mémoire.

Une méthode destroy spécifiée manuellement pourrait dissocier tous les écouteurs d'événement. Quelque chose comme:

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

  function handler(){ /**/ }

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

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

La méthode que j'ai trouvée pour supprimer mes instances de classe de la mémoire:

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