Skip to content

Instantly share code, notes, and snippets.

@rwaldron
Forked from tbtlr/def.js
Created March 22, 2011 01:37
Show Gist options
  • Save rwaldron/880602 to your computer and use it in GitHub Desktop.
Save rwaldron/880602 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.
*
*
* Example:
*
* def ("Person") ({
* init: function(){ ... }
* });
*
* def ("Ninja") << Person ({
* init: function(){ ... }
* });
*/
(function(global) {
// dummy subclass
function Subclass() { }
function augment(destination, source) {
// TODO: Ensure we fix IE to iterate over shadowed properties
// of those further down the prototype chain. There is also a
// bug in Safari 2 that will match the shadowed property and
// the one further down the prototype chain.
for (var key in source)
destination[key] = source[key];
}
function def(klassName, context) {
// create the `Class` on the given context (defaults to the global object)
var Klass =
(context || global)[klassName] = function Klass() {
// called with the `new` operator
if (this != global) {
// allow the init method to return a different class/object
return this.init && this.init.apply(this, arguments);
}
// called as a method
// defer setting up a superclass and adding plugins
def._super = Klass;
def._plugins = arguments[0] || { };
},
// static helper method
addPlugins =
Klass.addPlugins = function addPlugins(plugins) {
augment(Klass.prototype, plugins);
};
// we use valueOf to finish the setup of the
// deferred superclass and added plugins
addPlugins.valueOf = function() {
var Superclass = def._super;
if (Superclass) {
Subclass.prototype = Superclass.prototype;
Klass.prototype = new Subclass;
}
addPlugins(def._plugins);
def._super = def._plugins = null;
};
return addPlugins;
}
// expose
global.def = def;
})(this);
// Usage
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!');
}
});
var ninjy = new Ninja('JDD');
ninjy.speak();
ninjy.kick();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment