Friday, September 23, 2005
Class: Utility for Object Oriented JavaScript
I've created a really simple
To create a new class named
I've created a small demo of the code above; you should see the word's
See the demo.
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() { }
orattributeName: 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:
Links to this post:
<< Home
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() {}
};
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
Links to this post:
<< Home
Subscribe to Posts [Atom]