Return to Snippet

Revision: 23049
at February 25, 2012 01:39 by wizard04


Updated Code
/*****************************************
 * An implementation of class inheritance
 * 
 * This work is licensed under a Creative Commons Attribution 3.0 Unported License
 * http://creativecommons.org/licenses/by/3.0/
 *
 * Author: Andy Harrison, http://dragonzreef.com/
 * Date: 14 December 2011
 *****************************************/

//techniques and inspiration mainly from:
// http://ejohn.org/blog/simple-javascript-inheritance/
// http://joost.zeekat.nl/constructors-considered-mildly-confusing.html

var Class = (function(){
	
	"use strict";
	
	function Class(){}	//the base class
	Class.prototype.toString = function(){ return "[object Class]"; };
	Class.toString = function(){ return "[class Class]"; };
	
	//function to create a new class that inherits from this class
	//options argument must be an object. Possible options:
	//	className:	string used in .toString() for the constructor function, its prototype, and instances of the new class
	//	init:		function used to initialize a new instance of the class
	//	extensions:	object containing additional/overriding properties and methods for the new class
	//	return:		option 1: function used to return a value when the constructor is called without the `new` keyword
	//				option 2: value to be returned when the constructor is called without the `new` keyword
	Class.extend = function(options)
	{
		if(!options){
			options = {};
		}
		if(options.init && typeof options.init !== "function"){
			delete options.init;
		}
		if(typeof options.return !== "function"){	//if a function was not passed for options.return
			//make options.return into a function returning that value (undefined or otherwise)
			options.return = (function (retVal){ return function (){ return retVal; }; })(options.return);
		}
		
		/*** variables ***/
		
		var newPrototype, name, superPrototype = this.prototype, newProp;
		
		/*** functions ***/
		
		var emptyFn = function(){};
		
		var usesSuper;
		if((/foo/).test(function(){foo;})){	//browser check: if it allows the decompilation of functions (i.e., you can get the code as a string)
			usesSuper = function(fn){ return (/\b_super\b/).test(fn); };
		}
		else{
			usesSuper = function(){ return true; };	//can't tell, so assume the function uses `_super`
		}
		
		function addSuper(newFn, superFn)
		{
			return function()
			{
				//note: in this function, `this` refers to the new prototype
				
				var tmp = this._super;	//save the current value of ._super (in case the object has this property/method)
				
				//temporarily add a new ._super() method that is the overridden function on the super-class
				this._super = superFn;
				
				//execute the new function
				var ret = newFn.apply(this, arguments);
				
				this._super = tmp;	//restore this._super
				
				return ret;
			};
		}
		
		/*** the rest ***/
		
		emptyFn.prototype = this.prototype;
		newPrototype = new emptyFn();	//uninitialized instance of the super-class will be the prototype of the sub-class
		
		if(options.className){
			newPrototype.toString = function(){ return "[object "+options.className+"]"; };	//override .toString()
		}
		
		//add the new/overriding methods & properties
		if(options.extensions){
			for(name in options.extensions)
			{
				if(options.extensions.hasOwnProperty(name)){
					newProp = options.extensions[name];
					
					//if we're overwriting an existing function that uses `_super` in its code
					if(typeof newProp === "function" && typeof superPrototype[name] === "function" && usesSuper(newProp)){
						newPrototype[name] = addSuper(newProp, superPrototype[name]);	//use a modified function where `this._super` refers to the overridden function
					}
					else{
						newPrototype[name] = newProp;
					}
					
				}
			}
		}
		
		//if the initialization function uses `_super`
		if(options.init && usesSuper(options.init)){
			options.init = addSuper(options.init, this);	//use a modified function where `this._super` refers to the super-class (constructor)
		}
		
		//create the new class
		function Class()
		{
			if(this && this instanceof Class){	//if a new instance is being created (i.e., the `new` keyword is being used)
												//note: this condition will also be true in the odd case that this constructor is called in the context of an instance of itself. e.g.:
												//  var X = Class.extend({});
												//  var y = new X();
												//  y.z = X;
												//  y.z();	//this condition will now be true, even though the `new` keyword is not being used
				this.constructor = Class;	//this function is the constructor for the new instance (not the constructor of the prototype)
				if(options.init){
					options.init.apply(this, arguments);
				}
			}
			else{
				return options.return();
			}
		}
		Class.prototype = newPrototype;
		Class.extend = this.extend;	//make extend() a method of the new class
										//e.g.,
										//  var Foo = Class.extend({});
										//  var Bar = Foo.extend({});
										// instead of
										//  var Foo = Class.extend({});
										//  var Bar = Class.extend.call(Foo, {});
		if(options.className){
			Class.toString = function(){ return "[class "+options.className+"]"; };
		}
		
		return Class;
	};
	
	return Class;
	
})();

/*********************************************/
/*************** Example Usage ***************/
/*********************************************/
/*
var Pack = (function(){
	var allPacks = [];
	var Pack = Class.extend({
			className: "Pack",
			init: function(id, firstMember){
				this.packID = id;
				var wolves = [firstMember];
				console.log("Pack \""+id+"\" has its first member.");
				this.packSize = function(){return wolves.length},
				this.addMember = function(wolf){
					wolves.push(wolf);
					console.log("Pack \""+this.packID+"\" has a new member.");
				}
				allPacks.push(this);
			},
			extensions: {
				packID: ""
			},
			return: function(){
				return allPacks.length;
			}
		});
	Pack.packs = function(){return allPacks.length};
	Pack.allPacks = function(){return allPacks};
	return Pack;
})();

var Wolf = Class.extend({
		className: "Wolf",
		init: function(a){
			var age = a;
			console.log("A wolf has been spotted.");
			this.age = function(){return age};
		}
	});
var Cub = Wolf.extend({
		className: "Cub",
		init: function(){
			console.log("A cub is born!");
			this._super(0);	//call the initialization function of the Wolf class
		}
	});

function logPacks()
{
	console.log("\nThere "+(Pack.packs()==1?"is 1 pack":"are "+Pack.packs()+" packs")+" in the world.")
	console.log("Pack() returned "+Pack());
	//if(pack) console.log("pack.test() returned "+pack.test());	//expected: undefined
	var packs = Pack.allPacks();
	for(var i=0; i<packs.length; i++)
	{
		console.log("Wolves in pack \""+packs[i].packID+"\": "+packs[i].packSize());
	}
	console.log("\n");
}
logPacks();
var wolf = new Wolf(4);
var pack = new Pack("foo", wolf);
pack.test = Pack;
logPacks();
wolf = new Cub();
pack.addMember(wolf);
logPacks();
wolf = new Wolf(4);
var pack2 = new Pack("bar", wolf);
logPacks();
//*/

Revision: 23048
at September 17, 2011 05:07 by wizard04


Updated Code
/*****************************************
 * An implementation of class inheritance
 * 
 * This work is licensed under a Creative Commons Attribution 3.0 Unported License
 * http://creativecommons.org/licenses/by/3.0/
 *
 * Author: Andy Harrison, http://dragonzreef.com/
 * Date: 16 September 2011
 *****************************************/

//techniques and inspiration mainly from:
// http://ejohn.org/blog/simple-javascript-inheritance/
// http://joost.zeekat.nl/constructors-considered-mildly-confusing.html

var Class = (function(){
	
	function Class(){};	//the base class
	Class.prototype.toString = function(){ return "[object Class]" };
	Class.toString = function(){ return "[class Class]" };
	
	var preventInit = false;	//used to prevent an instance from initializing
	
	//function to create a new class that inherits from this class
	//options argument must be an object. Possible options:
	//	className:	string used in .toString() for the constructor function, its prototype, and instances of the new class
	//	init:		function used to initialize a new instance of the class
	//	extensions:	object containing additional/overriding properties and methods for the new class
	Class.subclass = function(options)
	{
		preventInit = true;
		var newPrototype = new this();	//uninitialized instance of the super-class will be the prototype of the sub-class
		preventInit = false;
		
		if(options.className) newPrototype.toString = function(){ return "[object "+options.className+"]" };
		
		newPrototype._superClass = this;		//super-class constructor
												//provides quick access to the initialization function of the super-class
												//e.g.,
												//  this._superClass.call(this, params);
												// instead of
												//  this.constructor.prototype.constructor.call(this, params);
		newPrototype._super = this.prototype;	//prototype of the super-class
												//provides quick access to overridden methods & properties
												//e.g.,
												//  this._super.someMethod.call(this);
												// instead of
												//  this.constructor.prototype.constructor.prototype.someMethod.call(this);
		
		for(var name in options.extentions) newPrototype[name] = options.extentions[name];	//add the new/overriding methods & properties
		
		//create the new class
		function Class()
		{
			this.constructor = arguments.callee;
			if(!preventInit && options.init) options.init.apply(this, arguments);
		}
		Class.prototype = newPrototype;
		Class.subclass = arguments.callee;	//make subclass() a method of the new class
											//e.g.,
											//  var Foo = Class.subclass({});
											//  var Bar = Foo.subclass({});
											// instead of
											//  var Foo = Class.subclass({});
											//  var Bar = Class.subclass.call(Foo, {});
		if(options.className) Class.toString = function(){ return "[class "+options.className+"]" };
		
		return Class;
	};
	
	return Class;
	
})();

/*********************************************/
/*************** Example Usage ***************/
/*********************************************/
/*
var Pack = (function(){
	var allPacks = [];
	var Pack = Class.subclass({
			className: "Pack",
			init: function(id, firstMember){
				this.packID = id;
				var wolves = [firstMember];
				console.log("Pack \""+id+"\" has its first member.");
				this.packSize = function(){return wolves.length},
				this.addMember = function(wolf){
					wolves.push(wolf);
					console.log("Pack \""+this.packID+"\" has a new member.");
				}
				allPacks.push(this);
			},
			extensions: {
				packID: ""
			}
		});
	Pack.packs = function(){return allPacks.length};
	Pack.allPacks = function(){return allPacks};
	return Pack;
})();

var Wolf = Class.subclass({
		className: "Wolf",
		init: function(a){
			var age = a;
			console.log("A wolf has been spotted.");
			this.age = function(){return age};
		}
	});
var Cub = Wolf.subclass({
		className: "Cub",
		init: function(){
			console.log("A cub is born!");
			this._superClass.call(this, 0);	//call the initialization function of the Wolf class
		}
	});

function logPacks()
{
	console.log("\nThere "+(Pack.packs()==1?"is 1 pack":"are "+Pack.packs()+" packs")+" in the world.")
	var packs = Pack.allPacks();
	for(var i=0; i<packs.length; i++)
	{
		console.log("Wolves in pack \""+packs[i].packID+"\": "+packs[i].packSize());
	}
	console.log("\n");
}
logPacks();
var wolf = new Wolf(4);
var pack = new Pack("foo", wolf);
logPacks();
wolf = new Cub();
pack.addMember(wolf);
logPacks();
wolf = new Wolf(4);
var pack2 = new Pack("bar", wolf);
logPacks();
*/

Revision: 23047
at March 26, 2011 00:04 by wizard04


Updated Code
/****************************************
An implementation of class inheritance in JavaScript.

Inspired by http://ejohn.org/blog/simple-javascript-inheritance/
/****************************************/

var Class = (function(){
	
	function Class(){};	//the base class
	Class.prototype.toString = function(){ return "[object Class]" };
	Class.toString = function(){ return "[class Class]" };
	
	var preventInit = false;	//used to prevent an instance from initializing
	
	//function to create a new class that inherits from this class
	Class.createSubClass = function(extentions, className)
	{
		preventInit = true;
		var newPrototype = new this();	//uninitialized instance of the super-class will be the prototype of the sub-class
		preventInit = false;
		
		if(className) newPrototype.toString = function(){ return "[object "+className+"]" };
		
		newPrototype._super = this.prototype;	//prototype of the super-class
												//provides quick access to overridden methods & properties
												//e.g.,
												//  this._super.init.call(this);
												// instead of
												//  this.constructor.prototype.constructor.prototype.init.call(this);
		
		for(var name in extentions) newPrototype[name] = extentions[name];	//add the new/overriding methods & properties
		
		//create the new class
		function Class()
		{
			this.constructor = arguments.callee;
			if(!preventInit && this.init) this.init.apply(this, arguments);
		}
		Class.prototype = newPrototype;
		Class.createSubClass = arguments.callee;	//make createSubClass() a method of the new class
													//e.g.,
													//  var Foo = Class.createSubClass({});
													//  var Bar = Foo.createSubClass({});
													// instead of
													//  var Foo = Class.createSubClass({});
													//  var Bar = Class.createSubClass.call(Foo, {});
		if(className) Class.toString = function(){ return "[class "+className+"]" };
		
		return Class;
	};
	
	return Class;
	
})();

/*********************************************/
/*************** Example Usage ***************/
/*********************************************/
/*
var Pack = (function(){
	var allPacks = [];
	var Pack = Class.createSubClass(
			{
				packID: "",
				init: function(id, firstMember){
					this.packID = id;
					var wolves = [firstMember];
					console.log("Pack \""+id+"\" has its first member.");
					this.packSize = function(){return wolves.length},
					this.addMember = function(wolf){
						wolves.push(wolf);
						console.log("Pack \""+this.packID+"\" has a new member.");
					}
					allPacks.push(this);
				}
			},
			"Pack"
		);
	Pack.packs = function(){return allPacks.length};
	Pack.allPacks = function(){return allPacks};
	return Pack;
})();

var Wolf = Class.createSubClass(
		{
			init: function(a){
				var age = a;
				console.log("A wolf has been spotted.");
				this.age = function(){return age};
			}
		},
		"Wolf"
	);
var Cub = Wolf.createSubClass(
		{
			init: function(){
				console.log("A cub is born!");
				this._super.init.call(this, 0);
			}
		},
		"Cub"
	);

function logPacks()
{
	console.log("\nThere "+(Pack.packs()==1?"is 1 pack":"are "+Pack.packs()+" packs")+" in the world.")
	var packs = Pack.allPacks();
	for(var i=0; i<packs.length; i++)
	{
		console.log("Wolves in pack \""+packs[i].packID+"\": "+packs[i].packSize());
	}
	console.log("\n");
}
logPacks();
var wolf = new Wolf(4);
var pack = new Pack("foo", wolf);
logPacks();
wolf = new Cub();
pack.addMember(wolf);
logPacks();
wolf = new Wolf(4);
var pack2 = new Pack("bar", wolf);
logPacks();
*/

Revision: 23046
at March 9, 2010 08:38 by wizard04


Updated Code
/****************************************
An implementation of class inheritance in JavaScript.

Inspired by http://ejohn.org/blog/simple-javascript-inheritance/
/****************************************/

var Class = (function(){
	
	function Class(){};	//the base class
	Class.prototype.toString = function(){ return "[object Class]" };
	
	var preventInit = false;	//used to prevent an instance from initializing
	
	//function to create a new class that inherits from this class
	Class.extend = function(extentions, className)
	{
		preventInit = true;
		var newPrototype = new this();	//uninitialized instance of the super-class will be the prototype of the sub-class
		preventInit = false;
		
		if(className) newPrototype.toString = function(){ return "[object "+className+"]" };
		
		newPrototype._super = this.prototype;	//prototype of the super-class
												//provides quick access to overridden methods & properties
												//e.g., this._super.go() instead of
												// this.constructor.prototype.constructor.prototype.go()
		
		for(var name in extentions) newPrototype[name] = extentions[name];	//add the new/overriding methods & properties
		
		//create the new class
		function Class()
		{
			this.constructor = arguments.callee;
			if(!preventInit && this.init) this.init.apply(this, arguments);
		}
		Class.prototype = newPrototype;
		Class.extend = arguments.callee;
		
		return Class;
	};
	
	return Class;
	
})();

/*********************************************/
/*************** Example Usage ***************/
/*********************************************/
/*
var Pack = (function(){
	var allPacks = [];
	var Pack = Class.extend(
			{
				packID: "",
				init: function(id, firstMember){
					this.packID = id;
					var wolves = [firstMember];
					console.log("Pack \""+id+"\" has its first member.");
					this.packSize = function(){return wolves.length},
					this.addMember = function(wolf){
						wolves.push(wolf);
						console.log("Pack \""+this.packID+"\" has a new member.");
					}
					allPacks.push(this);
				}
			},
			"Pack"
		);
	Pack.packs = function(){return allPacks.length};
	Pack.allPacks = function(){return allPacks};
	return Pack;
})();

var Wolf = Class.extend(
		{
			init: function(a){
				var age = a;
				console.log("A wolf has been spotted.");
				this.age = function(){return age};
			}
		},
		"Wolf"
	);
var Cub = Wolf.extend(
		{
			init: function(){
				console.log("A cub is born!");
				this._super.init.call(this, 0);
			}
		},
		"Cub"
	);

function logPacks()
{
	console.log("\nThere "+(Pack.packs()==1?"is 1 pack":"are "+Pack.packs()+" packs")+" in the world.")
	var packs = Pack.allPacks();
	for(var i=0; i<packs.length; i++)
	{
		console.log("Wolves in pack \""+packs[i].packID+"\": "+packs[i].packSize());
	}
	console.log("\n");
}
logPacks();
var wolf = new Wolf(4);
var pack = new Pack("foo", wolf);
logPacks();
wolf = new Cub();
pack.addMember(wolf);
logPacks();
wolf = new Wolf(4);
var pack2 = new Pack("bar", wolf);
logPacks();
*/

Revision: 23045
at February 19, 2010 08:33 by wizard04


Updated Code
//inspired by http://ejohn.org/blog/simple-javascript-inheritance/

var Class = (function(){
	
	function Class(){};	//the base class
	Class.prototype.toString = function(){ return "[object Class]" };
	
	var preventInit = false;	//used to prevent an instance from initializing
	
	//function to create a new class that inherits from this class
	Class.extend = function(extentions, className)
	{
		preventInit = true;
		var newPrototype = new this();	//uninitialized instance of the super-class will be the prototype of the sub-class
		preventInit = false;
		
		if(className) newPrototype.toString = function(){ return "[object "+className+"]" };
		
		newPrototype._super = this.prototype;	//prototype of the super-class
												//provides quick access to overridden methods & properties
												//e.g., this._super.go() instead of
												// this.constructor.prototype.constructor.prototype.go()
		
		for(var name in extentions) newPrototype[name] = extentions[name];	//add the new/overriding methods & properties
		
		//create the new class
		function Class()
		{
			this.constructor = arguments.callee;
			if(!preventInit && this.init) this.init.apply(this, arguments);
		}
		Class.prototype = newPrototype;
		Class.extend = arguments.callee;
		
		return Class;
	};
	
	return Class;
	
})();

/*********************************************/
/*************** Example Usage ***************/
/*********************************************/
/*
var Pack = (function(){
	var allPacks = [];
	var Pack = Class.extend(
			{
				packID: "",
				init: function(id, firstMember){
					this.packID = id;
					var wolves = [firstMember];
					console.log("Pack \""+id+"\" has its first member.");
					this.packSize = function(){return wolves.length},
					this.addMember = function(wolf){
						wolves.push(wolf);
						console.log("Pack \""+this.packID+"\" has a new member.");
					}
					allPacks.push(this);
				}
			},
			"Pack"
		);
	Pack.packs = function(){return allPacks.length};
	Pack.allPacks = function(){return allPacks};
	return Pack;
})();

var Wolf = Class.extend(
		{
			init: function(a){
				var age = a;
				console.log("A wolf has been spotted.");
				this.age = function(){return age};
			}
		},
		"Wolf"
	);
var Cub = Wolf.extend(
		{
			init: function(){
				console.log("A cub is born!");
				this._super.init.call(this, 0);
			}
		},
		"Cub"
	);

function logPacks()
{
	console.log("\nThere "+(Pack.packs()==1?"is 1 pack":"are "+Pack.packs()+" packs")+" in the world.")
	var packs = Pack.allPacks();
	for(var i=0; i<packs.length; i++)
	{
		console.log("Wolves in pack \""+packs[i].packID+"\": "+packs[i].packSize());
	}
	console.log("\n");
}
logPacks();
var wolf = new Wolf(4);
var pack = new Pack("foo", wolf);
logPacks();
wolf = new Cub();
pack.addMember(wolf);
logPacks();
wolf = new Wolf(4);
var pack2 = new Pack("bar", wolf);
logPacks();
*/

Revision: 23044
at February 19, 2010 08:31 by wizard04


Updated Code
//inspired by http://ejohn.org/blog/simple-javascript-inheritance/

var Class = (function(){
	
	function Class(){};	//the base class
	Class.prototype.toString = function(){ return "[object Class]" };
	
	var preventInit = false;	//used to prevent an instance from initializing
	
	//function to create a new class that inherits from this class
	Class.extend = function(extentions, className)
	{
		preventInit = true;
		var newPrototype = new this();	//uninitialized instance of the super-class will be the prototype of the sub-class
		preventInit = false;
		
		if(className) newPrototype.toString = function(){ return "[object "+className+"]" };
		
		newPrototype._super = this.prototype;	//prototype of the super-class
												//provides quick access to overridden methods & properties
												//e.g., this._super.go() instead of
												// this.constructor.prototype.constructor.prototype.go()
		
		for(var name in extentions) newPrototype[name] = extentions[name];	//add the new/overriding methods & properties
		
		//create the new class
		function Class()
		{
			this.constructor = arguments.callee;
			if(!preventInit && this.init) this.init.apply(this, arguments);
		}
		Class.prototype = newPrototype;
		Class.extend = arguments.callee;
		
		return Class;
	};
	
	return Class;
	
})();

/*********************************************/
/*************** Example Usage ***************/
/*********************************************/
/*
var Pack = (function(){
	var allPacks = [];
	var Pack = Class.extend(
			{
				packID: "",
				init: function(id, firstMember){
					this.packID = id;
					var wolves = [firstMember];
					console.log("Pack \""+id+"\" has its first member.");
					this.packSize = function(){return wolves.length},
					this.addMember = function(wolf){
						wolves.push(wolf);
						console.log("Pack \""+this.packID+"\" has a new member.");
					}
					allPacks.push(this);
				}
			},
			"Pack"
		);
	Pack.packs = function(){return allPacks.length};
	Pack.allPacks = function(){return allPacks};
	return Pack;
})();

var Wolf = Class.extend(
		{
			init: function(a){
				var age = a;
				console.log("A wolf has been spotted.");
				this.age = function(){return age};
			}
		},
		"Wolf"
	);
var Cub = Wolf.extend(
		{
			init: function(){
				console.log("A cub is born!");
				this._super.init.call(this, 0);
			}
		},
		"Cub"
	);

function logPacks()
{
	console.log("\nThere "+(Pack.packs()==1?"is 1 pack":"are "+Pack.packs()+" packs")+" in the world.")
	var packs = Pack.allPacks();
	for(var i=0; i<packs.length; i++)
	{
		console.log("Wolves in pack \""+packs[i].packID+"\": "+packs[i].packSize());
	}
	console.log("\n");
}
logPacks();
var wolf = new Wolf(4, "male");
var pack = new Pack("foo", wolf);
logPacks();
wolf = new Cub("male");
pack.addMember(wolf);
logPacks();
wolf = new Wolf(4, "male");
var pack2 = new Pack("bar", wolf);
logPacks();
*/

Revision: 23043
at February 19, 2010 08:21 by wizard04


Updated Code
//inspired by http://ejohn.org/blog/simple-javascript-inheritance/

var Class = (function(){
	
	function Class(){};	//the base class
	Class.prototype.toString = function(){ return "[object Class]" };
	
	var preventInit = false;	//used to prevent an instance from initializing
	
	//function to create a new class that inherits from this class
	Class.extend = function(extentions, className)
	{
		preventInit = true;
		var newPrototype = new this();	//uninitialized instance of the super-class will be the prototype of the sub-class
		preventInit = false;
		
		if(className) newPrototype.toString = function(){ return "[object "+className+"]" };
		
		newPrototype._super = this.prototype;	//prototype of the super-class
												//provides quick access to overridden methods & properties
												//e.g., this._super.go() instead of
												// this.constructor.prototype.constructor.prototype.go()
		
		for(var name in extentions) newPrototype[name] = extentions[name];	//add the new/overriding methods & properties
		
		//create the new class
		function Class()
		{
			this.constructor = arguments.callee;
			if(!preventInit && this.init) this.init.apply(this, arguments);
		}
		Class.prototype = newPrototype;
		Class.extend = arguments.callee;
		
		return Class;
	};
	
	return Class;
	
})();

/*********************************************/
/*************** Example Usage ***************/
/*********************************************/
/*
var Pack = (function(){
	var allPacks = [];
	var Pack = Class.extend(
			{
				packID: "",
				init: function(id, firstMember){
					this.packID = id;
					var wolves = [firstMember];
					console.log("Pack \""+id+"\" has its first member.");
					this.packSize = function(){return wolves.length},
					this.addMember = function(wolf){
						wolves.push(wolf);
						console.log("Pack \""+this.packID+"\" has a new member.");
					}
					allPacks.push(this);
				}
			},
			"Pack"
		);
	Pack.packs = function(){return allPacks.length};
	return Pack;
})();

var Wolf = Class.extend(
		{
			init: function(a){
				var age = a;
				console.log("A wolf has been spotted.");
				this.age = function(){return age};
			}
		},
		"Wolf"
	);
var Cub = Wolf.extend(
		{
			init: function(){
				console.log("A cub is born!");
				this._super.init.call(this, 0);
			}
		},
		"Cub"
	);

console.log("There "+(Pack.packs()==1?"is 1 pack":"are "+Pack.packs()+" packs")+" in the world.");
var wolf = new Wolf(4, "male");
var pack = new Pack("foo", wolf);
console.log("There "+(Pack.packs()==1?"is 1 pack":"are "+Pack.packs()+" packs")+" in the world.");
wolf = new Cub("male");
pack.addMember(wolf);
console.log("There "+(Pack.packs()==1?"is 1 pack":"are "+Pack.packs()+" packs")+" in the world.");
console.log("--> Wolves in pack \""+pack.packID+"\": "+pack.packSize());
wolf = new Wolf(4, "male");
var pack2 = new Pack("bar", wolf);
console.log("There "+(Pack.packs()==1?"is 1 pack":"are "+Pack.packs()+" packs")+" in the world.");
console.log("--> Wolves in pack \""+pack.packID+"\": "+pack.packSize());
console.log("--> Wolves in pack \""+pack2.packID+"\": "+pack2.packSize());
*/

Revision: 23042
at February 3, 2010 14:13 by wizard04


Updated Code
//most of this is based on http://ejohn.org/blog/simple-javascript-inheritance/

(function(){	//need a closure for the preventInit variable
	
	function Class(){};	//the base class
	Class.prototype.toString = function(){ return "[object Class]" };
	this.Class = Class;	//make it accessible from outside of this closure
	
	var preventInit = false;	//used to prevent an instance from initializing
	
	//function to create a new class that inherits from this class
	Class.extend = function(extentions, className)
	{
		var thisClass = this.prototype;	//prototype of the super-class
		
		preventInit = true;
		var newPrototype = new this();	//uninitialized instance of the super-class; will be the prototype of the sub-class
		preventInit = false;
		
		if(className) newPrototype.toString = function(){ return "[object "+className+"]" };
		
		newPrototype._super = thisClass;	//will provide quick access to overridden methods & properties in the super-class
											//e.g., this._super.go() instead of this.constructor.prototype.go()
		
		for(var name in extentions) newPrototype[name] = extentions[name];	//add the new/overriding methods & properties
		
		//create the new class
		function Class()
		{
			this.constructor = arguments.callee;
			if(!preventInit && this.init) this.init.apply(this, arguments);
		}
		Class.prototype = newPrototype;
		Class.extend = arguments.callee;
		
		return Class;
	};
	
})();

/*********************************************/
/*************** Example Usage ***************/
/*********************************************/

var Foo = Class.extend({
		s: function(){ return "foo" }
	}, "Foo");
var Bar = Foo.extend({
		str: "",
		s: function(){
			return this._super.s() + this.str + this.b();
		},
		init: function(txt){
			this.str = txt;
			var baz = "baz";
			this.b = function(){ return baz };
		}
	}, "Bar");

var b = new Bar("bar");

alert(b.s());			//"foobarbaz"
alert(b._super.s());	//"foo"
alert(b.str);			//"bar"
alert(b.b());			//"baz"
alert(b.baz);			//undefined

Revision: 23041
at February 3, 2010 14:07 by wizard04


Updated Code
//most of this is based on http://ejohn.org/blog/simple-javascript-inheritance/

(function(){	//need a closure for the preventInit variable
	
	function Class(){};	//the base class
	Class.prototype.toString = function(){ return "[object Class]" };
	this.Class = Class;	//make it accessible from outside of this closure
	
	var preventInit = false;	//used to prevent an instance from initializing
	
	//function to create a new class that inherits from this class
	Class.extend = function(extentions, className)
	{
		var thisClass = this.prototype;	//prototype of the super-class
		
		preventInit = true;
		var newPrototype = new this();	//uninitialized instance of the super-class; will be the prototype of the sub-class
		preventInit = false;
		
		if(className) newPrototype.toString = function(){ return "[object "+className+"]" };
		
		newPrototype._super = thisClass;	//will provide quick access to overridden methods & properties in the super-class
											//e.g., this._super.go() instead of this.constructor.prototype.go()
		
		for(var name in extentions) newPrototype[name] = extentions[name];	//add the new/overriding methods & properties
		
		//create the new class
		function Class()
		{
			this.constructor = arguments.callee;
			if(!preventInit && this.init) this.init.apply(this, arguments);
		}
		Class.prototype = newPrototype;
		Class.extend = arguments.callee;
		
		return Class;
	};
	
})();

/*********************************************/
/*************** Example Usage ***************/
/*********************************************/

var Foo = Class.extend({
		s: function(){ return "foo" }
	}, "Foo");
var Bar = Foo.extend({
		str: "",
		s: function(){
			var baz = "baz";
			this.b = function(){ return baz };
			return this._super.s() + this.str + baz
		},
		init: function(txt){ this.str = txt }
	}, "Bar");

var b = new Bar("bar");

alert(b.s());			//"foobarbaz"
alert(b._super.s());	//"foo"
alert(b.str);			//"bar"
alert(b.b());			//"baz"
alert(b.baz);			//undefined

Revision: 23040
at February 3, 2010 13:52 by wizard04


Updated Code
//most of this is based on http://ejohn.org/blog/simple-javascript-inheritance/

(function(){	//need a closure for the preventInit variable
	
	function Class(){};	//the base class
	Class.prototype.toString = function(){ return "[object Class]" };
	this.Class = Class;	//make it accessible from outside of this closure
	
	var preventInit = false;	//used to prevent an instance from initializing
	
	//function to create a new class that inherits from this class
	Class.extend = function(extentions, className)
	{
		var thisClass = this.prototype;	//prototype of the super-class
		
		preventInit = true;
		var newPrototype = new this();	//instance of the super-class; will be the prototype of the sub-class
		preventInit = false;
		
		if(className) newPrototype.toString = function(){ return "[object "+className+"]" };
		
		newPrototype._super = thisClass;	//will provide quick access to overridden methods & properties in the super-class
											//e.g., this._super.go() instead of this.constructor.prototype.go()
		
		for(var name in extentions) newPrototype[name] = extentions[name];	//add the new/overriding methods & properties
		
		//create the new class
		function Class()
		{
			this.constructor = arguments.callee;
			if(!preventInit && this.init) this.init.apply(this, arguments);
		}
		Class.prototype = newPrototype;
		Class.extend = arguments.callee;
		
		return Class;
	};
	
})();

/*********************************************/
/*************** Example Usage ***************/
/*********************************************/

var Foo = Class.extend({
		s: function(){ return "foo" }
	}, "Foo");
var Bar = Foo.extend({
		str: "",
		s: function(){
			var baz = "baz";
			this.b = function(){ return baz };
			return this._super.s() + this.str + baz
		},
		init: function(txt){ this.str = txt }
	}, "Bar");

var b = new Bar("bar");

alert(b.s());			//"foobarbaz"
alert(b._super.s());	//"foo"
alert(b.str);			//"bar"
alert(b.b());			//"baz"
alert(b.baz);			//undefined

Revision: 23039
at February 3, 2010 13:22 by wizard04


Updated Code
//most of this is based on http://ejohn.org/blog/simple-javascript-inheritance/

(function(){	//need a closure for the preventInit variable
	
	function Class(){};	//the base class
	Class.prototype.toString = function(){ return "[object Class]" };
	this.Class = Class;	//make it accessible from outside of this closure
	
	var preventInit = false;	//used to prevent an instance from initializing
	
	//function to create a new class that inherits from this class
	Class.extend = function(extentions, className)
	{
		var thisClass = this.prototype;	//prototype of the super-class
		
		preventInit = true;
		var newPrototype = new this();	//instance of the super-class; will be the prototype of the sub-class
		preventInit = false;
		
		if(className) newPrototype.toString = function(){ return "[object "+className+"]" };
		
		newPrototype._super = thisClass;	//will provide quick access to overridden methods & properties in the super-class
											//e.g., this._super.go() instead of this.constructor.prototype.go()
		
		for(var name in extentions) newPrototype[name] = extentions[name];	//add the new/overriding methods & properties
		
		//create the new class
		function Class()
		{
			this.constructor = arguments.callee;
			if(!preventInit && this.init) this.init.apply(this, arguments);
		}
		Class.prototype = newPrototype;
		Class.extend = arguments.callee;
		
		return Class;
	};
	
})();

/*********************************************/
/*************** Example Usage ***************/
/*********************************************/

var Foo = Class.extend({
		s: function(){ return "foo" }
	}, "Foo");
var Bar = Foo.extend({
		str: "",
		s: function(){ return this._super.s()+this.str },
		init: function(txt){ this.str = txt }
	}, "Bar");

var b = new Bar("bar");

alert(b.s());	//alerts "foobar"

Revision: 23038
at January 28, 2010 16:44 by wizard04


Initial Code
function Class(){}
Class.prototype.toString = function(){ return "[object Class]" };

Class.extend = function(extentions, className)
{
	var thisClass = this.prototype;	//prototype of the super-class function
	var newPrototype = new this();		//instance of the super-class function; will be the prototype of the sub-class
	
	if(className) newPrototype.toString = function(){ return "[object "+className+"]" };
	
	newPrototype._super = thisClass;	//will provide quick access to overridden methods & properties in the super-class
										//e.g., this._super.go() instead of this.constructor.prototype.go()
	for(var name in extentions) newPrototype[name] = extentions[name];	//add the new/overriding methods & properties
	
	//create the new class
	function Class()
	{
		this.constructor = Class;
		if(this.init) this.init.apply(this, arguments);
	}
	Class.prototype = newPrototype;
	Class.extend = arguments.callee;
	
	return Class;
};

/*************************************/
/*************** Usage ***************/
/*************************************/

var Foo = Class.extend({
		s: function(){ return "foo" }
	}, "Foo");
var Bar = Foo.extend({
		str: "",
		s: function(){ return this._super.s()+this.str },
		init: function(txt){ this.str = txt }
	}, "Bar");

var f = new Foo;
var b = new Bar("bar");

alert(b.s());	//alerts "foobar"

Initial URL


Initial Description
An implementation of class inheritance in JavaScript.

Initial Title
JavaScript Classes

Initial Tags
javascript, class, object

Initial Language
JavaScript