An introduction to Object Oriented Programming in Javascript. This example creates a small user control that can be used repeatedly and independantly on the same web page.
OOP in Javascript: Introduction
Matt R.Warren of Contegra
April 2004
Yes, believe it
or not Javascript is an object oriented programming langauge (almost). Not an
exceptionally powerful one mind. And ok, it may not be a ‘full’ OOP language
with inheritance, interfacing etc… like C++/C# or Java. However, saying that,
Javascript does allow you to create lightweight objects. Afterall, you use the
browsers DOM in an OOP based hierarchal manner, so why not your own controls
and data?
So why create an
object at all? In fact, what is an object. Simply put, an object (in programmer
speak) is a way of encapsulating data and functionality into a (more-or-less)
stand-alone unit that is essentially re-useable. This is exceptionally useful.
It allows you to group data and functionality logically, or in the case of this
small example, render to the browser a simple control multiple times… and
all instances of the object are all independant from each other.
Just some things
you need to keep in mind. the DOM has some restrictions. It is hard to uniquely
identify individual tags if they all share the same ID’s or NAME’s. This is
a potential problem as effectively we are trying to create form controls that
function independantly. Usually to avoid this problem I create an ‘index’ that
is handled purely from within my object definition. However this approach is
a little complicated and is beyond the scope of this small tutorial. Saying
that however, we still need some way of creating individuality within the DOM,
so for the purposes of this example I am using a very cut down version of what
I usually use and I have created a globally scoped variable called ‘myObjectIndex’.
It’s usage is examplained later.
Functions in Javascript
are fairly flexible beasts. They don’t just allow you to run small segments
of procedurised code. They are also used to form the skeletal framework you
require to create an object. Lets go through the example and I will explain
what it happening as I go. (all explanations are in comment form)…
<script>
// This globally
scoped variable is used internally by 'myObject'
// to
create DOM uniqueness. Don't modify this yourself, leave it
// to 'myObject' to manipulate. There *are* better ways of doing
// this, however I am using this method for simplicity.
var
myObjectIndex = 0
// The object
definition. Yes, its a function! and yes, it excepts
// parameters. These parameters form a part of what is generally
// called the objects 'constructor' (defined more completely within
// the object and explained later). It allows you to create an
// object using some initial information you wish it to use.
function
myObject(sName,sSurname,sAge)
{
// Now we
are within the 'object' we need to allow it to create
// itself within its own memory area. This is done using the 'new'
// command. The 'me' variable then contains the newly created
// Object ready for your use.
var me = new constructor(sName,sSurname,sAge)
// The 'constructor' function may create the object, but
we are
// able to add information to the object whenever we wish. Any
// information added to an object that contains data like a variable
// is called a 'property'. The following property takes the value of
// global
'myObjectIndex' for the objects unique identity, then
// increments 'myObjectIndex' by 1 ready for the next object
// creation (if there is one).
me.Index = myObjectIndex++;
// The following additions to the object are slightly
different.
// Further down in the example, are some functions defined WITHIN
// this function (our object). This means that they are locally
// scoped to code within the object, so, if we want to give 'public'
// use of the functions, we have to specifically allow access to
// those functions. This is an easy thing to do. Just as in the
// 'me.Index',
give the function you wish to make generally available
// an alias name, then make it equal to the name of the function
// (notice
that you need to leave out the brackets! using
// 'me.GetFullname = getFullname()' will execute the function
// instead.)
// Once a function has been added in this way, they are called
// 'Methods'.
me.GetFullname = getFullname;
me.Render = render;
// Once initialization of the object is completed, return
'me'
// (which IS the object) to the caller.
return me;
// NB: Notice that all the following functions are defined WITHIN the
// 'myObject' function...
// This is the function that creates the object for you. Notice the
// use of the 'this' object accessor. The use of 'this' is important
// as the 'this' keyword allow's us to create the object and add
// properties and methods as we wish.
DO NOT expose this function
// outside of the object using 'me.Constructor = constructor'! This
// function should remain private.
function constructor(sName,sSurname,sAge)
{
this.Name
= sName;
this.Surname
= sSurname;
this.Age
= sAge;
return
this;
}
// This is the 'GetFullname' method that you allow general
access
// to via the 'me.GetFullname = getFullname'.
function getFullname()
{
return
me.Name + ' ' + me.Surname;
}
// Again, coders are allowed access via 'me.Render = render'.
function render()
{
// This methods uses javascript to render the HTML for
this object.
// notice the use of the 'me.Index' property to uniquely identify
// the object in the DOM.
document.write('My
Index is: ');
document.write(me.Index);
document.write('<br>');
document.write('<input
type="text" id="fullName');
document.write(me.Index);
document.write('"
name="fullName');
document.write(me.Index);
document.write('"
value="');
// notice here that I am using the internal verion of
the GetFullname
// method. There is no real need to, but I wanted to demonstrate that
// there is no difference WITHIN the object between 'me.GetFullname()'
// and 'getFullname()'.
document.write(getFullname());
document.write('"><br>');
document.write('<input
type="button" id="allDetails');
document.write(me.Index);
document.write('"
name="allDetails');
document.write(me.Index);
document.write('"
value="All Details"><p>');
// Now that we have rendered the HTML, we can assign event
handlers.
// This is where the uniqueness within the DOM by using the me.Index
// becomes important.
// We use 'getElementById' to access the required render HTML tag,
// then assign a function to the event in a similar manner to the way
// you assign a function to the object (notice again, no brackets).
document.getElementById("allDetails"+
me.Index).onclick = handleAllDetailsClick;
return;
// This function handles the 'onclick' event. Notice again that it's
// locally scoped to this method. This isn't essential, but it's good
// organisation.
function
handleAllDetailsClick()
{
alert('I
am ' + me.GetFullname() + '\n\nAged: ' + me.Age + ' Years.');
}
}
}
// Thats the object fully defined. Now its use...
// Usually within OOP langauges, to create a new object
instance,
// you
always use the 'new' keyword. Javascript is no exception
// to this rule. However, experience has taught me that most Web
// developers do not truely understand OOP. Don't get me wrong,
// Web developers are a fine bunch, it's what I do. But when your
// used to ASP or PHP (even though you CAN create objects in both),
// OOP isn't a high priority (VB6 COM DLL's don't truely count as
// full OOP either). So I made a habit of making the object create
// it's
own memory area internally (me = new constructor(...)).
// This cut down on bugs dramatically and saved headaches. Basically
// that makes the usage of the 'new' keyword purely optional, as
// the following should demonstrate...
// Individually created examples...
var o_Data
= new myObject("Matt","Warren",26);
var o_Data1 = myObject("Matt","Warren",26);
var o_Data2 = myObject("Rich","price",24);
o_Data1.Name = "Andy";
o_Data1.Surname = "Jump";
o_Data1.Age = "21";
o_Data.Render();
o_Data1.Render();
o_Data2.Render();
// Or for
a bit more fun and less work with more objects...
// objects created and placed into an array. An array of Objects
// is called a 'collection'...
var
collection = new Array
(
myObject("Collection","Entity 1",16),
myObject("Collection","Entity 2",26),
myObject("Collection","Entity 3",36),
myObject("Collection","Entity 4",46),
myObject("Collection","Entity 5",56)
);
// Now enumerate the collection, and render them all...
for(var ind in collection)
collection[ind].Render();
</script>
Have fun!
Matt R.Warren