This is my personal blog. The views expressed on these pages are mine alone and not those of my employer.

Friday, September 23, 2005

Class: Utility for Object Oriented JavaScript

I've created a really simple Class class that helps me do JavaScript OOP programming; you might find it useful yourself. I'll show you first how to use it, then I'll give you the small framework code. One aspect that is unique about the code is that it does not extend Object.prototype, which the Prototype framework does; it is evil and dangerous to extend Object.prototype, because it can destroy some useful JavaScript techniques for others.

To create a new class named Page with the simple framework, for example, you would do the following:
var Page = new Class();

Page.prototype = {
/** public */ construct: function(pageName, pageData) {
this.pageName = pageName;
this.pageData = pageData;
},

/** public */ sayHello: function() {
alert("Hello World");
alert("pageName="+this.pageName);
alert("pageData="+this.pageData);
},

/** private */ someAttribute: new String(),
/** private */ aPrivateMethod: function() {}
};

var mainPage = new Page("Main", "Some Page Data");
mainPage.sayHello();
New classes extend the Class object:
var Page = new Class();
The Class object will automatically call your constructor, which must be named construct:
construct: function(pageName, pageData) {
this.pageName = pageName;
this.pageData = pageData;
}
Notice the use of the this idiom, where you can pass in arguments to initialize your object in the constructor and use the same name in your local object variables; this is a useful pattern in Java that it is possible to replicate in JavaScript, so you don't have to do something like this, which is annoying:
construct: function(newPageName, newPageData) {
this.pageName = newPageName;
this.pageData = newPageData;
}
Next, give your methods and attributes in the following form:
methodName: function() { }
or
attributeName: attributeValue
Each attribute and method must be comma seperated, except for the last one:
methodName: function() { },
attributeName: function() { }
You will notice that I put a small comment before each attribute or method to signify whether it is public or private. JavaScript has no real way to do access control (though there are some hacks to achieve it, I don't like them and they make the code complex). To help other coders, I simply use comments to make access control clear:
/** public */ publicMethod: function(someArgument) {},
/** private */ privateMethod: function(someArgument) {}
Finally, when you are ready to use your new class, you can just instantiate it like a normal class:
var mainPage = new Page("Main", "Some Page Data");
mainPage.sayHello();
Here's the magic code for Class; you must put this at the top of your JavaScript or into a utility library somewhere:
function Class() {
return function() {
if (this.construct != undefined) {
// call the subclass's constructor
this.construct.apply(this, arguments);
}
};
};
Class is simply a function that itself returns a function. This inner function simply dynamically calls your construct method, passing in the arguments using the magic JavaScript keyword arguments, which contains all of a calling functions arguments.

I've created a small demo of the code above; you should see the word's Hello World printed, and the values of pageName and pageData that were passed into an instance of Page named mainPage.

See the demo.

Comments:
The demo is a bit too simple. Without inheritance, calling super construct and/or calling a super class method and so on there isn't much reason to go through this.

For your demo it seems like doing it the old school way is more useful.

function Page(pageName, pageData) {
this.pageName = pageName;
this.pageData = pageData;
}

Page.prototype = {
/** public */ sayHello: function() {
alert("Hello World");
alert("pageName="+this.pageName);
alert("pageData="+this.pageData);
},

/** private */ someAttribute: "",
/** private */ aPrivateMethod: function() {}
};
 
You're right; I need to define an extend() method to make this truly useful, otherwise it doesn't really do much.
 
Post a Comment

Subscribe to Post Comments [Atom]



Links to this post:

Create a Link



<< Home

This page is powered by Blogger. Isn't yours?

Subscribe to Posts [Atom]