Skip to content

Instantly share code, notes, and snippets.

@kirbysayshi
Created July 14, 2010 15:04
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save kirbysayshi/475511 to your computer and use it in GitHub Desktop.
Save kirbysayshi/475511 to your computer and use it in GitHub Desktop.
/*
* def.js: Simple Ruby-style inheritance for JavaScript
*
* Copyright (c) 2010 Tobias Schneider
* This script is freely distributable under the terms of the MIT license.
*/
(function(global) {
// used to defer setup of superclass and plugins
var deferred;
function addPlugins(plugins) {
augment(this.prototype, plugins);
return this;
}
// TODO: Ensure we fix IE to iterate over shadowed properties
// of those further up the prototype chain. There is also a
// bug in Safari 2 that will match the shadowed property and
// the one further up the prototype chain.
function augment(destination, source) {
for (var key in source) {
destination[key] = source[key];
}
}
// dummy subclass
function Subclass() { }
function def(klassName, context) {
context || (context = global);
// create class on given context (defaults to global object)
var Klass =
context[klassName] = function Klass() {
// called as a constructor
if (this != context) {
// allow the init method to return a different class/object
return this.init && this.init.apply(this, arguments);
}
// called as a method
// defer setup of superclass and plugins
deferred._super = Klass;
deferred._plugins = arguments[0] || { };
};
// add static helper method
Klass.addPlugins = addPlugins;
// called as function when not
// inheriting from a superclass
deferred = function(plugins) {
return Klass.addPlugins(plugins);
};
// valueOf is called to setup
// inheritance from a superclass
deferred.valueOf = function() {
var Superclass = deferred._super;
if (!Superclass) return Klass.valueOf();
Subclass.prototype = Superclass.prototype;
Klass.prototype = new Subclass;
Klass.superclass = Superclass;
Klass.prototype.constructor = Klass;
Klass.addPlugins(deferred._plugins);
deferred._super = deferred._props = null;
return Klass.valueOf();
};
return deferred;
}
// expose
global.def = def;
})(this);
// Example
def ('Person') ({
'init': function(name) {
this.name = name;
},
'speak': function(text) {
alert(text || 'Hi, my name is ' + this.name);
}
});
def ('Ninja') << Person ({
'kick': function() {
this.speak('I kick u!');
}
, 'speak': function(text){
alert("My function: " + text);
}
});
var ninjy = new Ninja('JDD');
ninjy.speak("whoa!");
ninjy.kick();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment