Search code examples
javascriptprototypedispose

How do I dispose of a prototype in JS?


I've got a thorny issue and although the answer may be obvious, I cannot see how to do what I'm trying to do.

I have created a script library for my application that uses JS prototypes and templating to dynamically instantiate DOM elements AND to wire those elements up with handlers. An example is the following:

var ppane = new AWP.iuiPanel(theObject, { title: 'Select filter(s)', idDisplay: 'block', idString: params.sender._options['title'] });

AWP.iuiPanel is a class defined as a function prototype, e.g:

AWP.iuiPanel = function() { <i'm a constructor> }
AWP.iuiPanel.prototype = { <a bunch of methods here> }

The methods inside the instance create a DOM element (in this case a floating panel) and establish event bindings for it, wire up its control elements, etc.

The advantage of going down this path is that through a single call to create a new instance of a class I can also build the associated DOM element, and once instantiated, the class methods that have been wired up will execute against the element to do things like position it relative to a target object, respond to relevant browser events, etc.

The problem I have is when I want to dispose of this construct. I can dispose the DOM element easily. But I then still have the class instance in memory with methods wired to browser events looking for the DOM element that has been disposed. I need to be able to dispose not only of the DOM element, but also of the class instance, and I cannot figure out how to do that.

How can one dispose of a function prototype once declared? This seems like it ought to be simple, but I'm finding it to be decidedly not so.

For background info, here is an example of a class as I am defining it:

This is necessarily pseudo-code(ish)...

AWP.trivialExample = function(someDomRef, someOptionSet) {
   this._id = someOptionSet['name'];
   this._width = someOptionSet['width'];
   this._width = someOptionSet['height'];
   this._domRef = someDomRef;
   this._object = '';

   this.constructDOM();
   this.wireEvents();

}

AWP.trivialExample.prototype = {

   constructDOM: function() {
      // build a complex DOM element relative to a provided DOM ref using the
      // desired and height.  This uses a template and I won't give a precise example
      // of such a template.
      jQuery("#aTemplate").tmpl(someJSONData).appendTo("body");

   },

   positionRelative: function() {
      // this function would get the location of a specific DOM ref and always maintain
      // a relative position for the DOM element we just constructed

   },

   wireEvents: function() {
      // hook up to events using JQuery (example)
      jjQuery(window).resize(this.positionRelative);

   }

}

The above is a trivial example that would take in a DOM object reference, and then it would dynamically construct a new DOM element and it would wire up to browser events to always maintain relative position between these two objects when the page is sized.

When I dispose of the new object, I also need to dispose of the class instance and I cannot find a simple way to do that.

All help appreciated.

Thanks;


Solution

  • A suggestion on the event listeners referencing a deleted DOM node:

    just as you have a 'wireEvents', you should have a corresponding 'unwireEvents' in case you decide to stop using the object. addEventListener() needs to be used in conjuction with removeEventListener() in this case. You should modify your prototype to remove Event listeners when the corresponding DOM Node is 'disposed', as you say.