Ajax Dan

Hi, I'm Dan, a Web Developer from New Zealand. I'm new to javascript and ajax, having spent most of my career developing Windows applications, and although I've liked the JavaScript code snipets that I've seen on other sites, I think there's still room for a new set of (more) integrated tools to be developed and, of course, shared with others. This blog is my attempt to help other web developers to understand and develop better object-oriented ajax tools.

Name:
Location: Griffin, Brisbane, Australia

Thursday, April 06, 2006

Object Oriented JavaScript - Part 3: Calling Base Class Functions

It's important for an object oriented language to have the ability to override a base class function. Further to this, and something few JavaScript OO developers include, is the ability to call the base class function from the function that overrides it.

The current inherits function does allow the developer to call base class functions through the this.base extension, however any changes made to primitive data types (strings, numbers and boolean data types) will not be reflected within the descendant class. A further change to the inherits function is required to overcome this deficiency.

Object.prototype.inherits = function(object) {
this.base = {_ancestor: null, _descendant: this};
if (typeof object == "object") {
this.base._ancestor = object;
}
else {
this.base._ancestor = new object(arguments.length > 1 ? Array.prototype.slice.call(arguments, 1) : null);
}
for (property in this.base._ancestor) {
if (! this[property]) {
this[property] = this.base._ancestor[property];
}

else if (typeof this.base._ancestor[property] == "function") {
this.base[property] = function() {
return this._ancestor[property].apply(this._descendant, arguments);
}
}

}
}


The inherits function now creates a substitute function for all methods that have been overridden. Each created function still makes a call to the overridden method, but uses the apply extension to pass the descendant object to it. This ensures that any variables updated are done within the descendant class rather than the base class.

function accumulator() {
this.sum = 0;
this.add = function(addEnd) { // Adds one number
this.sum += addEnd;
}
}
function aggregator() {
this.add = function() { // Adds many numbers
for (var i = 0; i < arguments.length; i++) {
this.base.add(arguments[i]);
}
}
this.inherits(accumulator);
}
var calculator = new aggregator();
calculator.add(5, 7, 4);
alert(calculator.sum); // Displays "16"

Sunday, April 02, 2006

Object Oriented JavaScript - Part 2: Passing Constructor Arguments

The current inherits function is ideal for simple objects that don't require arguments to be passed to their constructor. In order to cater for the more complex objects that do require them, we'll need to add some new functionality.

Object.prototype.inherits = function(object) {
if (typeof object == "object") {
this.base = object;
}
else {
this.base = new object(arguments.length > 1 ? Array.prototype.slice.call(arguments, 1) : null);
}
for (property in this.base) {
if (! this[property]) {
this[property] = this.base[property];
}
}
}

In addition to passing arguments, the inherits function now also allows the developer to pass a fully instantiated object, if this is their preference.

function fruitTree(fruit) {
this.fruit = fruit;
}

function appleTree(variety) {
this.variety = variety;
this.toString = function() {
return this.variety + " " + this.fruit + " Tree";
}
this.inherits(new fruitTree("Apple"));
// Or use "this.inherits(fruitTree, "Apple");"
}

var myTree = new appleTree("Granny Smith");

alert(myTree); // Displays "Granny Smith Apple Tree"

You can place the inherits function anywhere within the constructor, but placing it after variable and function definitions ensures that duplicate base class variables and functions aren't needlessly copied across (and then later overwritten).

Next: Calling Base Class Functions

Saturday, April 01, 2006

Object Oriented JavaScript - Part 1: Inheritance

Having come from a significant background in Windows development, programming in objects is what I'm used to. Now using Javascript, I've had to code my own object oriented functionality.

Javascript doesn't have object inheritance built in, but it is possible to add this functionality to the Object class using the prototype extension.

Object.prototype.inherits = function(object) {
this.base = new object;
for (property in this.base) {
if (! this[property]) {
this[property] = this.base[property];
}
}
}

Base class functions defined in the constructor would have been copied if I had simply added object.call(this), however this would not have copied any functions defined through the prototype class. Copying each property from an instantiated class ensures that all functions (and public variables) are available within the descendant class (if they aren't already defined).

By attaching the inherits function to the Object class, it automatically becomes available to any objects that you create.

function ObjectA() {
this.whoAmI = function() {
return "I am " + this.constructor.toString().match(/function\s*(\w+)/)[1];
}
}

function ObjectB() {
this.inherits(ObjectA);
}

var myObject = new ObjectB();

alert(myObject.whoAmI()); // Displays "I am ObjectB"

Next: Passing Constructor Arguments
Then: Calling Base Class Functions