Point of Style: Differentiating Objects from Constructors in DHTML Widgets

So, you’ve read about Object Oriented Javascript, and how it can help make your Ajax and DHTML and other Web 3.14159 widgets and tools more robust.

You’ve learned about how the prototype object can allow you to customize objects in a memory-efficient way, and maybe even learned a few code patterns for building objects.

You’ve even gone so far as to minimize your Global usage by putting everything under one global object.

So, let’s say that you have a Menu widget. There might be more than one, but then again, there may not be. You might have to refer to it again, and you might not. And even if you dont’ have to, it’d be convenient to leave the door open. How do you name your constructor function, and what do you call the object it creates?

Do you create a MenuConstructor function, and then create an object called Menu? But new MenuConstructor(); looks like I’m creating a constructor, not using a constructor to create an object. new Menu() is much more appealing. So, do you have something like var myMenu = new Menu()? If all your stuff is namespaced under Application.Section, it can be pretty hairy.

I’ve been running into this problem a bit, and in the past, have usually had two confusingly named objects, either one of which could have been the constructor or the object, or a singleton class that created exactly one object, and couldn’t be used on a page more than once. Then one day, I put on my complicator’s gloves, and hatched up a glorious plan to build a “Manager” class that could provide an interface to any class and listen to events and do all sorts of cool stuff. It was interesting to build a class that could create any generic class (quite similar to the Abstract Factory OOP design pattern.)

It was cool. And the resulting code was a very complicated pain in the ass that did way more than I really needed it to.

Here’s my new approach, (where “element” is the Dom node that we’re tweaking up.)

var Menu = function (element) {
  doStuff();
  // make sure that element has an ID, and generate it if it doesn't.
  element = YAHOO.util.Dom.get(element);
  YAHOO.util.Dom.generateId(element);
  Menu.Instances[ element.id ] = this;
};
Menu.Instances = {};

So, in all the scripts I write from now on, unless there’s a pretty good reason not to, I’m going to set up an “Instances” member on the constructor, and store my created objects in there. The tricky part is figuring out how unique they should be. In most DHTML tasks, you only want to instrument a given Dom node once. So, you can even test to make sure that it exists and throw an error if the same element is being instrumented twice.

In other cases, it might make sense to instrument the same node twice, in which case, you may need to set up the key generation a little differently.

2 Responses to “Point of Style: Differentiating Objects from Constructors in DHTML Widgets”

  1. On April 13th, 2007 at 20:58:36, Peter Goodman Said:

    I just seems like the circular references would cause a memory leak in IE… or is that not an issue/the case?

  2. On April 14th, 2007 at 13:45:27, Isaac Said:

    Good question!

    Circular references as such are not the problem. In order to cause a memory leak, the reference chain must pass into Dom/ActiveX space and then back into Javascript space. For example:

    // reference from JS object -> Dom
    var o = { b : document.body };

    // reference from Dom back to that JS object
    document.body.foo = o;

    http://isaacschlueter.com/2006/10/msie-memory-leaks/

    In this case, since there are only links being created by JS objects to other JS objects, it’s fine. And, in fact, the references aren’t circular: the constructor object refers to the created objects, but not the other way around.

Leave a Reply

Comments are moderated like crazy using a variety of plugins. There is a very high likelihood that your comment won't show up right away, especially if you have never commented here before, but it was not deleted.

Please be patient, and do not post your comment more than once. It will show up once it is approved.

You must be logged in to post a comment.