Skip to content

Instantly share code, notes, and snippets.

@robozevel
Forked from gunderwonder/inheritance.js
Created July 7, 2012 11:02
Show Gist options
  • Save robozevel/3065866 to your computer and use it in GitHub Desktop.
Save robozevel/3065866 to your computer and use it in GitHub Desktop.
A simple JavaScript inheritance system
/*
* A simple JavaScript inheritance system
* (Like Prototype's `Class.create()`, only without the crazy method wrapping and function decompilation)
*
* Usage
* var A = Class.create({
* // `$init` is the constructor
* $init: function(x, y) {
* this.x = x;
* this.y = y;
* },
* toString : function() { return [this.x, this.y].join(' '); }
* });
*
* // `B` is a child of `A`
* var B = Class.create(A, {
* $init : function(x, y, z) {
* // use this.$ to apply the base class constructor
* this.$(this, arguments);
* this.z = z;
* },
* toString : function() { return [this.x, this.y, this.z].join(' '); }
* });
*
* // Also:
* var B = A.extend({
* $init : function(x, y, z) {
* A.$(this, arguments);
* this.z = z;
* },
* toString : function() { return [this.x, this.y, this.z].join(' '); }
* });
*
* var B = A.extend(function(x, y, z) {
* A.$(this, arguments);
* this.z = z;
* },{
* toString : function() { return [this.x, this.y, this.z].join(' '); }
* });
*
* var a = new A(10, 10), b = new B(10, 10, 20);
* a.toString() => '10 10'
* b.toString() => '10 10 20'
*/
var Class = {
config: {
initMethod: "$init",
superMethod: "$super",
applyShorthand: "$"
},
initObject: function(method) {
var o = {};
o[Class.config.initMethod] = method || function() {};
return o;
},
create: function(baseClass, methods) {
var $init = Class.config.initMethod,
$super = Class.config.superMethod,
$base = Class.config.applyShorthand;
switch(typeof methods) {
case 'undefined':
methods = baseClass || Class.initObject(baseClass);
baseClass = null;
break;
case 'function':
methods = Class.initObject(methods);
break;
default:
break;
}
function superMethod(methodName) {
var method = methods[methodName];
if (constructor.superClass) {
method = constructor.superClass[methodName] || method;
}
return method;
}
function constructor() {
for (var methodName in methods) {
methods[methodName][$super] = superMethod(methodName).bind(this);
}
methods[$init].apply(this, arguments);
}
if (baseClass) {
var subClass = function() {};
subClass.prototype = baseClass.prototype;
constructor.prototype = new subClass;
constructor.superClass = baseClass.prototype;
}
methods[$init] = methods[$init] || function() {};
constructor.prototype.constructor = constructor;
for (var methodName in methods) {
constructor.prototype[methodName] = methods[methodName];
}
constructor[$base] = Function.apply;
return constructor;
}
};
Function.prototype.extend = function(initialize, methods) {
if (arguments.length === 0) {
methods = this;
} else if (typeof methods === 'object') {
methods[Class.config.initMethod] = initialize;
}
return Class.create(this, methods || initialize || {});
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment