Sunday 25 September 2011

JS Classes


First step(Basic class definition)

  • private variables are declared with the 'var' keyword inside the object, and can only be accessed by private functions and privileged methods.
  • private functions are declared inline inside the object's constructor (or alternatively may be defined via var functionName=function(){...}) and may only be called by privileged methods (including the object's constructor).
  • privileged methods are declared with this.methodName=function(){...} and may invoked by code external to the object.
  • public properties are declared with this.variableName and may be read/written from outside the object.
  • public methods are defined by Classname.prototype.methodName = function(){...} and may be called from outside the object.
  • prototype properties are defined by Classname.prototype.propertyName = someValue
  • static properties are defined by Classname.propertyName = someValue
function Mammal(name){
	//private var
	var id;
	//private method
	var set_id = function(){
		id = Mammal.id++;
	}
	//public property
	this.name=name;
	this.offspring=[];
	//privileged method
	this.getId = function(){
		return id;
	}
	//constructor
	set_id();
}
//public methods
Mammal.prototype.haveABaby=function(){ 
	var newBaby=new Mammal("Baby "+this.name);
	this.offspring.push(newBaby);
	return newBaby;
} 
Mammal.prototype.toString=function(){ 
	return '[Mammal "'+this.name+'"]';
}
//static property
Mammal.id = 1;

Second step(Inheritance)

  • You cause a class to inherit using ChildClassName.prototype = newParentClass();.
  • You need to remember to reset the constructor property for the class using ChildClassName.prototype.constructor=ChildClassName.
  • You can call ancestor class methods which your child class has overridden using the Function.call() method.
  • Javascript does not support protected methods .

Cat.prototype = new Mammal();        // Here's where the inheritance occurs 
Cat.prototype.constructor=Cat;       // Otherwise instances of Cat would have a constructor of Mammal 
function Cat(name){ 
	this.name=name;
} 
Cat.prototype.toString=function(){ 
	return '[Cat "'+this.name+'"]';
} 

var someAnimal = new Mammal('Mr. Biggles');
var myPet = new Cat('Felix');
alert('someAnimal is '+someAnimal);   // results in 'someAnimal is [Mammal "Mr. Biggles"]' 
alert('myPet is '+myPet);             // results in 'myPet is [Cat "Felix"]' 

myPet.haveABaby();                    // calls a method inherited from Mammal 
alert(myPet.offspring.length);        // shows that the cat has one baby now 
alert(myPet.offspring[0]);            // results in '[Mammal "Baby Felix"]' 

Using the .constructor property
Mammal.prototype.haveABaby=function(){ 
	var newBaby=new this.constructor("Baby "+this.name);
	this.offspring.push(newBaby);
	return newBaby;
} 
...
myPet.haveABaby();                    // Same as before: calls the method inherited from Mammal 
alert(myPet.offspring[0]); 

Calling 'super' methods

Cat.prototype.haveABaby=function(){ 
	Mammal.prototype.haveABaby.call(this);
	alert("mew!");
}

Making your own 'super' property

Cat.prototype = new Mammal();
Cat.prototype.constructor=Cat;
Cat.prototype.parent = Mammal.prototype;
...
Cat.prototype.haveABaby=function(){ 
	var theKitten = this.parent.haveABaby.call(this);
	alert("mew!");
	return theKitten;
} 

Spoofing pure virtual classes

LivingThing = { 
	beBorn : function(){ 
		this.alive=true;
	} 
} 
...
Mammal.prototype = LivingThing;
Mammal.prototype.parent = LivingThing;   //Note: not 'LivingThing.prototype' 
Mammal.prototype.haveABaby=function(){ 
	this.parent.beBorn.call(this);
	var newBaby=new this.constructor("Baby "+this.name);
	this.offspring.push(newBaby);
	return newBaby;
} 

Convenient Inheritance

Function.prototype.inheritsFrom = function( parentClassOrObject ){ 
	if ( parentClassOrObject.constructor == Function ) 
	{ 
		//Normal Inheritance 
		this.prototype = new parentClassOrObject;
		this.prototype.constructor = this;
		this.prototype.parent = parentClassOrObject.prototype;
	} 
	else 
	{ 
		//Pure Virtual Inheritance 
		this.prototype = parentClassOrObject;
		this.prototype.constructor = this;
		this.prototype.parent = parentClassOrObject;
	} 
	return this;
} 
//
//
LivingThing = { 
	beBorn : function(){ 
		this.alive = true;
	} 
} 
//
//
function Mammal(name){ 
	this.name=name;
	this.offspring=[];
} 
Mammal.inheritsFrom( LivingThing );
Mammal.prototype.haveABaby=function(){ 
	this.parent.beBorn.call(this);
	var newBaby = new this.constructor( "Baby " + this.name );
	this.offspring.push(newBaby);
	return newBaby;
} 
//
//
function Cat( name ){ 
	this.name=name;
} 
Cat.inheritsFrom( Mammal );
Cat.prototype.haveABaby=function(){ 
	var theKitten = this.parent.haveABaby.call(this);
	alert("mew!");
	return theKitten;
} 
Cat.prototype.toString=function(){ 
	return '[Cat "'+this.name+'"]';
} 
//
//
var felix = new Cat( "Felix" );
var kitten = felix.haveABaby( ); // mew! 
alert( kitten );                 // [Cat "Baby Felix"] 








No comments:

Post a Comment