...

View Full Version : Object Orientated Javascript Help



rossmason
05-29-2005, 03:51 AM
I am having problems with object orientated JavaScript and I am ready to tear my damn hair out!!!

I currently work for a web development company and we use JavaScript and content editable div’s for our web content management system. Quite frankly the code for this is pretty messy and I saw Object Oriented JavaScript maybe as our saviour to move some of the core code common to different components in the system to an extra level where it wouldn’t be ‘hacked’ on a regular basis.

The problem is that when a class is inherited I need to be able to get access to the parent classes variables and methods from within the child class with minimum code in the client class or I will have a hard time convincing the other developers to use the parent classes.

The test code I am using to try to get this to work is below. As you can see from the debug alerts I cannot access the parent class variables from inside the child class but outside the child class this doesn't seem to be a problem.

My main concearn is keeping the code in the child classes minimal. Any help anyone can give will be greatfully recieved.


<html>
<head>
<script language="javascript" type="text/javascript">

function initialise(){
ManagedElements = new Array
docElements = document.all
objTotal = docElements.length

/*Search through each body element and import any IScript objects into the ManagedElements array
as a javascript class of the name set by the attribute IType.

*/

for (objCount=0; objCount < objTotal; objCount++){
if (docElements[objCount].getAttribute("IScript") == "true") {
alert("Found IScriptElement: " + docElements[objCount].id + ". importing as class: " + docElements[objCount].getAttribute("IType"))

// Try and create a Class of type found in IType and return an error if Class cannot be found
try{
ManagedElements[ManagedElements.length] = (eval("new " + docElements[objCount].getAttribute("IType")))
ManagedElements[ManagedElements.length -1].initialise(docElements[objCount])
}
catch(error){
alert("Debug: Could not find class '" + docElements[objCount].getAttribute("IType") + "'. Import of iScript Element '" + docElements[objCount].id + "' failed.")
}

}
}

for (i=0; i<ManagedElements.length; i++){
alert(ManagedElements[i].id)
}
}


/*-----------------------------------------------------------
------------------ CLASS IComponent -------------------------
------------------ ------------------------------------------*/
function IComponent(){
this.initialise = IComponent_initialise
}

function IComponent_initialise(htmlObj){
this.htmlObject = htmlObj
this.id = htmlObj.id
this.type = htmlObj.getAttribute("IType")
}
/*-----------------------------------------------------------*/



TextEditor1.prototype = new IComponent();
TextEditor1.prototype.constructor = IComponent;
TextEditor1.superclass = IComponent.prototype;

function TextEditor1(){
alert("Creating IComponent. IType = TextEditor1")
alert(this.id)
}

TextEditor2.prototype = new IComponent();
TextEditor2.prototype.constructor = IComponent;
TextEditor2.superclass = IComponent.prototype;

function TextEditor2(){
alert("Creating IComponent. IType = TextEditor2")
alert(this.id)
}
</script>
</head>
<body onload="javascript:initialise()">
<div id="div1" IScript="true" IType="TextEditor1" style="border:1px dashed #ff0000" contenteditable="true">retret</div>
<div id="div2" IScript="true" IType="TextEditor2" style="border:1px dashed #ff0000" contenteditable="true">retret</div>
</body>
</html>

dumpfi
05-29-2005, 07:58 AM
Here is a working example:

function IComponent() { }
IComponent.prototype.initialise = IComponent_initialise;
IComponent.prototype.id = 1;
function IComponent_initialise(htmlObj){
this.htmlObject = htmlObj
this.id = htmlObj.id
this.type = htmlObj.getAttribute("IType")
}
function TextEditor() {
this.alertId = function() { alert(this.id); }
}
TextEditor.prototype = IComponent.prototype;
TextEditor.prototype.superclass = IComponent;
window.onload = function() {
y = new TextEditor();
y.alertId();
alert(y.initialise);
}
Object.prototype contains only the methods and properties you define with Object.property.abc = ...
Thats why the TextEditor instance has the alertId()-method although the prototype property of the class is replaced by the "parent's" class one.

So you have to define all methods and properties you want to "inherit" via the prototype property.

dumpfi

DHTML Kitchen
05-29-2005, 08:03 AM
Inheritance doesn't work so well in javascript. You can force it to work, but the language doesn't lend itself so well to that.

Here's my advice:
1) Use the Factory pattern instead of your initialize function
2) Use aggregation -- the "has a" relationship, not inheritance.
3) Don't use eval. Eval is slow. You can always avoid eval and it is usually easy to find a better way.
4) Do not declare global variables within funcitons (you forgot the var keyword on several counts).
5) You should not have to store the type of your object inside itself, This is very non-OO:
this.type = htmlObj.getAttribute("IType")


Replace this with a Factory:

try{
ManagedElements[ManagedElements.length] = (eval("new " + docElements[objCount].getAttribute("IType")))
ManagedElements[ManagedElements.length -1].initialise(docElements[objCount])
}
catch(error){
alert("Debug: Could not find class '" + docElements[objCount].getAttribute("IType") + "'. Import of iScript Element '" + docElements[objCount].id + "' failed.")
}


IComponent = function() {

};



IComponent.getInstance = function(iType) {
if(iType == ...)
return someType.getInstance();

...

return null;
};

Kor
05-30-2005, 12:14 PM
what is the
return null
doing?



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum