Article
Rethinking JavaScript Objects
Any developer that has worked with JavaScript for any amount of time is familiar with the arduous task of creating custom JavaScript objects. Coming from a background in Java, I’ve spent many hours trying to figure out how to make JavaScript objects act more like Java objects in every way. There just seems to be so much repetition in the way we need to define JavaScript objects, and I find that frustrating. After some thought and a lot of reading, I came up with a few ways to help eliminate some of the repetition that has plagued my coding for years.
Rethinking Inheritance
JavaScript, as many of us know, uses a prototype-based method of object inheritance. This states that if I have a “class” called ClassA, ClassB can inherit from it if I make ClassB’s prototype into an instance of ClassA, like so:
function ClassA () {
}
function ClassB() {
}
ClassB.prototype = new ClassA;
This method has been augmented by the “object masquerading” technique used to copy an object’s properties (but not its methods) to another object. In order to fully inherit everything from ClassA into ClassB, we actually need to do this:
function ClassA () {
}
function ClassB() {
this.superclass = ClassA;
this.superclass();
delete this.superclass;
}
ClassB.prototype = new ClassA;
That’s an awful lot of code to accomplish something that is handled in Java like this:
Class ClassA {
}
Class ClassB extends ClassA {
}
Going over this again and again in my development, I found myself growing increasingly annoyed at the repetitive and wasteful nature of all that JavaScript code I’d had to write just to inherit properties and methods from one class to another. Then I came across an interesting concept on Netscape’s DevEdge site.
Bob Clary, a Netscape Evangelist, wrote a function so simple I wondered why I hadn’t thought of it myself. In his article, “inheritFrom – A Simple Method of Inheritance Upon Demand”, he defines a simple method called inheritFrom() that can be used to copy all the properties and methods of an object to another object.
Essentially the same as every clone method every written in JavaScript, this function uses a for..in loop to iterate through the properties and methods of a given object, and copy them to another. A call would be made like this:
inheritFrom(ClassB, ClassA);
While that’s a good idea, it just didn’t fit into my coding style. I still consider JavaScript constructors as classes, and I write them thinking more of defining a Java class than a JavaScript constructor. It occurred to me that if I extended the native JavaScript Object class to include a method that did the same thing, all objects would automatically get this method, and I could essentially write something that looked and felt very similar to Java logic. My solution: the extends() method.
Just like Clary’s solution, the extends() method works on the basis that all properties and methods can be iterated through using bracket notation such as this:
object[“Property”]; //Same as object.Property
The method itself looks like this:
Object.prototype.extends = function (oSuper) {
for (sProperty in oSuper) {
this[sProperty] = oSuper[sProperty];
}
}
This method accepts one parameter, oSuper, which is an instantiation of the class that we’d like to inherit from (or “extend”). The inner code is essentially the same as Clary’s inhertFrom() function, with the exceptions that:
- I’m using the this keyword to indicate the object that is receiving the copied attributes, and
- I removed the try..catch block so that that the method could also be used in Netscape Navigator 4.x.
Nicholas is a user interface designer for Web applications at MatrixOne, Inc. in Massachusetts. He's published several articles about JavaScript and DHTML on various sites, including