Coding, is? Fun!

Monday, February 05, 2007

Object Oriented Javascript - an introduction

Working in Photon, I get a constant stream of queries from developers about Object Oriented Javascript (OOJ). Many, of course, come across OOJ syntax in some maintenance code - and completely panic. I don't blame them - this was my reaction too when I first saw syntax as below:

Customer.prototype.getName=function(id){
return this.name;
}

What the hell does the above mean? What is prototype? Why is the function keyword placed after an equals sign?
I will present here a very essential guide to OOJ. At the end of it, hopefully you won't be scared by OOJ syntax; will be able to maintain such code properly; and even create your own classes in Javascript. To create Ajax applications, it is essential to be able to create client side object libraries.
Some of the abilities of an OO language are:
- to define classes;
- to define constructors for initialization code;
- to define methods attached to such a class;
Let us see how these work with an example. Let us say you want to create an address book. The address class has three properties - address1, city and pin code. You would like to populate the addresses from a html page. Any validation will be handled by the address class.
In OOJ, you create a class and a constructor at the same time:
function Address()
{
this.address1 = "";
this .city = "";
this.pincode = "";
}

You have defined a Address class. It looks just like a function; but Javascript knows it is a class if you use the above class like this:
var addr = new Address();
Note that you define the constructor at the same time; the above function is also the constructor. You can pass parameters to it thus:
function Address(address1, city, pincode)
{
this.address1 = address;

this.city =
city;
this.pincode = pincode;
}

var addr = new Address(addr1, city, pin);
Now, the members of this class are declared within the class. This is similar to C# or Java:
var addr = new Address();
addr.address1 = "1 second street";
You can refer to member properties using the "." operator.
So, we have defined a class; a constructor; an some properties. Now it is time to attach some functions. Let us say there is a function to validate the pincode; there are two ways to attach it.
The first is:
function Address(address1, city, pincode)
{
this.address1 =
address;

this.city =
city;
this.pincode = pincode;
this.validatePin=function()
{
var re = /\d{6}/g;
return re.test(this.pincode);
}
}
So, validatePin is a method of class Address. To use it:
var addr = new Address();
addr.pincode = "600020";
addr.validatePin();

You can handle parameters too.
The second way to attach methods is using the prototype object. In Javascript, every object has a internal hidden property called the prototype. You use the prototype property to attach methods to a class:
function Address(address1, city, pincode)
{
this.address1 = address;
this.city =
city;
this.pincode = pincode;
}

Address.prototype.validatePin = function()
{
var re = /\d{6}/g;
return re.test(this.pincode);
}
The weird syntax of functions confuses people. But, in Javascript functions are first class objects and can be declared anonymously.
In both the above examples, note that you refer to other properties in the class using the "this" keyword.
What if you wanted to call a method from another method?
var addr = new Address();
addr.pincode = "600020";
addr.validate();
Address.prototype.validate = function()
{

return this.validatePin(this.pincode);
}
Address.prototype.validatePin = function(pin)
{
var re = /\d{6}/g;
return re.test(pin);
}

The most common mistake in OOJ programming is to forget to use the this keyword when referring to other members. This will throw a syntax error.
The above illustrates creating and using a class using OOJ. Classes can use other classes; therefore you can create a proper class library. As an example, you can have an address collection as below:
function AddressList()
{
this.addresses = new Array();
this.currentAddress = null;
this.defaultAddress = new Address();
}
AddressList.prototype.addAddress=function(address)
{
this.addresses[this.addresses.length] =
address;
}
and so forth.
These class libraries are the basis for creating Rich Internet Applications (RIA). If you used global functions and properties everywhere, you will rapidly lose the ability to maintain.

OOJ does not have the ability to automatically handles setters and getters. It also does not have the ability to handle access modifiers such as private, public or protected. This does cause some problems from a pure OO perspective.
OOJ will work in all browsers that can handle Javascript - it is a fundamental feature of the language.

OOJ and Events
When calling methods on a class you do not have to worry much about object references. But, when you dynamically create user interface elements such as divs, you may have to handle events on them. It gets somewhat tricky to handle this:
function TextBox()
{
this.divTag.addEventListener("onkeydown",
this.keyHandler,false);

}
TextBox.prototype.keyHandler=function(ev)
{
alert(ev.which);
}
The above code will work.
I suggest that when you work with Javascript, and you use external files, consider using OOJ; it adds lots of clarity to the code.

3 Comments:

  • Hey...Very useful post,
    actually I read this post long back, I stopped after a first few lines that time i didnt understand, now for the past few days i have been learnin OOJS, now it makes more sense to me. I guess, it would serve as a good startup for beginners. I have some quries reg this, will get those to you soon. Even regarding JSON(Java Script Object Notation)I have some queries.

    By Anonymous Anonymous, at 2:59 AM  

  • Thank you. This is extremely helpful. Why wasn't/isn't this approach encouraged from the beginning when learning JS?

    By Anonymous Anonymous, at 6:19 AM  

  • Good, clear intro to what can be a scary topic. Thank you.

    By Blogger Unknown, at 3:59 AM  

Post a Comment

<< Home