(function(){ //Defines the top level Class function Class() { } Class.prototype.construct = function() {}; // getPrototypeOf polyfill if (typeof Object.getPrototypeOf !== "function") { Class.prototype.getPrototypeOf = "".__proto__ === String.prototype ? function (object) { return object.__proto__; } : function (object) { // May break if the constructor has been tampered with return object.constructor.prototype; }; } else Class.prototype.getPrototypeOf = Object.getPrototypeOf; Class.extend = function(def) { var classDef = function() { if (arguments[0] !== Class) { this.construct.apply(this, arguments); } }; var proto = new this(Class); proto.applyMembers(def, this.prototype); classDef.prototype = proto; //Give this new class the same static extend method classDef.extend = this.extend; return classDef; }; Class.prototype.applyMembers = function (def, proto) { for (var n in def) { var item = def[n]; if (item instanceof Function) { item._super = proto; item.function_name = n; } this[n] = item; } }; Class.prototype._super = function (args) { var method = args.callee._super[args.callee.function_name]; if (method) return method.apply(this, args); }; wpj.Class = Class; })();