I wrote this as a distilled version of what holds Q (and proto-q) together, the inheritance pattern:
var App = (function () { var win = this, doc = win.document, mixin = function (/* {Object}, {Object}, ... */) { var args = Array.prototype.slice.apply(arguments), r = args.shift(), o, m; while (args.length) { m = args.shift(); for (o in m) { if (m.hasOwnProperty(o)) { r[o] = m[o]; } } } return r; }; return { doc: doc, mixin: mixin, win: win }; }()); App.Class = function (options) { if (!(this instanceof App.Class)) { return new App.Class(options); } this.name = "App.Class"; this.config = options; }; App.Class.prototype.clone = function (options) { return new this.constructor(App.mixin({}, this.config, options)); }; App.Class.prototype.subClass = function (name, defaults) { var parent = this, ns = name.split(".").slice(1), n = App; while (ns.length > 1) { n = n[ns.shift()]; } n[ns[0]] = function (options) { if (!(this instanceof n[ns[0]])) { return new n[ns[0]](options); } this.config = App.mixin({}, parent.config, defaults, options); this.__super__ = parent; this.name = name; }; App.mixin(n[ns[0]].prototype, parent.constructor.prototype); }; var instanceOfAppClass = App.Class(); console.log("instanceOfAppClass:", instanceOfAppClass); console.log("type:", typeof instanceOfAppClass); console.log("instanceOf App.Class ?", instanceOfAppClass instanceof App.Class); console.log("constructor:", instanceOfAppClass.constructor); var clone = instanceOfAppClass.clone(); console.log("clone:", clone); console.log("type:", typeof clone); console.log("instanceOf App.Class ?", clone instanceof App.Class); console.log("constructor:", clone.constructor); clone.subClass("App.subclass"); console.log("subclass:", App.subclass); console.log("type:", typeof App.subclass); console.log("constructor:", App.subclass.constructor); var instanceOfSubClass = App.subclass(); console.log("instanceOfSubClass:", instanceOfSubClass); console.log("type:", typeof instanceOfSubClass); console.log("instanceOf App.Class ?", instanceOfSubClass instanceof App.Class); console.log("instanceOf App.subclass ?", instanceOfSubClass instanceof App.subclass); console.log("access to parent (super instanceOf App.Class ?):", instanceOfSubClass.__super__ instanceof App.Class) console.log("super:", instanceOfSubClass.__super__); console.log("super name:", instanceOfSubClass.__super__.name); console.log("constructor:", instanceOfSubClass.constructor); var propertyTest = App.Class({one: 1, two: "two", three: {o:"1", n:"2", e:"3"}, four: [1,2,3,4]}); var propertyClone = propertyTest.clone(); console.log("cloned properties:", propertyTest.config.two === propertyClone.config.two); propertyTest.subClass("App.propertySub", {}); console.log("subclassed properties:", propertyTest.config.two === App.propertySub().config.two); propertyTest.subClass("App.propertySubOverride", {one: "one"}); console.log("override parent properties control:", propertyTest.config.two === App.propertySubOverride().config.two); console.log("override parent properties override:", propertyTest.config.one === App.propertySubOverride().config.one); var overrideInstance = App.propertySubOverride({one: 1}); console.log("override class properties:", propertyTest.config.one === overrideInstance.config.one); |
