JavaScript: Object Orientated Programming

January 28, 2010 by JavaScript  

JavaScript is an object based language, some even use the term prototype-orientated language (perhaps more accurate).

In this post I am going to have a quick look at what essentially represents OOP within the JavaScript realm, and have a look at prototyping.

In languages like C# & PHP, we create objects from classes/structs etc, within JavaScript however, we need to use functions to define our objects, observe:

/*constructor*/
function base(name)
{
	/*private*/ var title = 'base object:';
	/*public*/this.name = name;
	/*global*/value = 10;
	
	this.display = /*public*/function(message)
	{
		alert(title + message);
	}
	
	this.toString = /*public*/function()
	{
		return "base";
	}
}

var a = new base('test1'); // instantiated object
a.display(a); // base object:base
alert(a.name); // base object:
alert(a.title); // undefined
alert(value); // 10

Notice my comments, I gave certain functions fictitious access modifiers (eg private/public) to give you an idea of scope visibility of these members.

The title property can only be accessed within the instantiated object (like a private member), the this.name field is publically available using the object. Notice the value field, if we omit the var keyword, it becomes a global variable - one can access it anywhere within the scope of our page.

Constructor? Well, the whole function essentially represents our constructor.

Another term used in OOP is "inheritance", which relates to the fact that we can add certain methods/properties etc from another class (function in this case), to our class(function) in question. In JavaScript this is achieved using prototypes, observe:
/*constructor*/
function derived()
{		
	/*private*/function getDate()
	{
		return new Date();
	}
	
	this.showdate = /*public*/function()
	{
		this.display(getDate());
	}
}
	
derived.prototype = /*inherit*/new base('test2');
derived.prototype.toString = /*overrides*/function()
{
	return "derived";
}

var b = new derived();
b.showdate();
b.display(b);
alert(b.name);

Inheritance is achieved by assigning an instance of the function we wish to "inherit" from, to our prototype - which copies the members within that instance to our derived object.

It is even possible to override inherited members, using prototypes, eg. the toString method.

Prototypes also allow us to add functionality to existing built-in objects, similar to extension methods, in the following snippet we "alias" the addEventListener method in Mozilla to the attachEvent method - by "extending" the built-in Object.
if (!window.attachEvent) {
	Object.prototype.attachEvent = function(event, handler)	{
		this.addEventListener(event.substring(2), handler, false);					
	}
}


Note : Have a look at the "private" getDate function within our derived function, if you attempt to access the instance you're working with (using the this keyword), you will notice that you actually get an instance of the current window object and not the actual instance it "lives" in - rather dodgy? Which means getDate isn't really a private method in the true sense of the word.

Its also possible to create objects using javascript object notation (JSON), these objects unfortunately lack constructors, meaning we can't create/reuse new instances, since we're actually defining an inline object.
var a = {
	display : function(message)
	{
		alert(message);
	},
	toString : function()
	{
		return 'a';
	}
};


Unless you're planning to return the object from a "constructor" function...(mmmm???)
function base()
{
	var a =
	{
		// Object definition
	};
	return a;
}


Finally I noticed on a few sites people asking about creating static methods, we can achieve something similar by doing the following:
derived.somefunction = /*static*/function()
{
	alert('somefunction called');
}
derived.somefunction();


Leave a Comment


April 28, 2010 by KIswono

nice ^^ thanks!