diff --git a/ui (gen4)/lib/object.js b/ui (gen4)/lib/object.js index 294d5525..69fb2335 100755 --- a/ui (gen4)/lib/object.js +++ b/ui (gen4)/lib/object.js @@ -13,8 +13,102 @@ define(function(require){ var module = {} /*********************************************************************/ -// XXX BUG: if the constructor is called from it's instance this will -// return the instance and not a new object... +// Make a JavaScrip object constructor... +// +// +// Make a constructor with an object prototype... +// makeConstructor(, ) +// -> constructor +// +// Make a constructor with an init function prototype... +// makeConstructor(, ) +// -> constructor +// +// Make a constructor with a prototype (object/function) and a class +// prototype... +// makeConstructor(, , ) +// makeConstructor(, , ) +// -> constructor +// NOTE: the defines a set of class methods and +// attributes. +// +// +// +// The resulting constructor can produce objects in one of these ways: +// +// Basic constructor use... +// constructor() +// new constructor +// new constructor() +// -> instance +// +// Pass arguments to the constructor... +// constructor([, ...]) +// new constructor([, ...]) +// -> instance +// +// +// All produced objects are instances of the constructor +// instance instanceof constructor +// -> true +// +// +// +// Init protocol: +// 1) the base instance object is prepared (.__proto__ is set) +// 2) if is present, then it is called with instance as +// context and passed the constructor arguments +// 3) if .__init__(..) is present, it is called with the instance +// as context and passed the constructor arguments. +// +// +// +// Inheritance: +// A simple way to build C -> B -> A chain would be: +// +// var A = makeConstructor('A', {}) +// +// // NOTE: the prototype is an instance and not a constructor, +// // this is obvious if one considers that in JS there are +// // no classes and inheritance is done via object prototypes +// // but this might be a gotcha to people coming from the +// // class-object world. +// var B = makeConstructor('B', A()) +// +// var C = makeConstructor('C', B()) +// +// var c = C() +// +// c instanceof C // -> true +// c instanceof B // -> true +// c instanceof A // -> true +// +// A.prototype.x = 123 +// +// c.x // -> 123 +// +// +// +// Motivation: +// The general motivation here is to standardise the constructor protocol +// and make a single simple way to go with minimal variation. This is due +// to the JavaScript base protocol though quite simple, being too flexible +// making it very involved to produce objects in a consistent manner by +// hand, especially in long running projects, in turn spreading all the +// refactoring over multiple sites and styles. +// +// This removes part of the flexibility and in return gives us: +// - single, well defined protocol +// - one single spot where all the "magic" happens +// - full support for existing JavaScript ways of doing things +// - easy refactoring without touching the client code +// +// +// XXX might be a good idea to be able to make an instance without +// initializing it... +// ...mainly for inheritance. +// ...would also be helpful in this case to call all the +// constructors in the chain var makeConstructor = module.makeConstructor = function makeConstructor(name, a, b){ @@ -23,6 +117,8 @@ function makeConstructor(name, a, b){ var _constructor = function Constructor(){ /* + // XXX BUG: if the constructor is called from it's instance this will + // return the instance and not a new object... // in case this is called as a function (without new)... if(this.constructor !== _constructor){ // NOTE: the following does the job of the 'new' operator but @@ -57,6 +153,10 @@ function makeConstructor(name, a, b){ }) //obj.__proto__.constructor = _constructor + // explicit init... + if(proto instanceof Function){ + proto.apply(obj, arguments) + } // load initial state... if(obj.__init__ != null){ @@ -86,7 +186,6 @@ function makeConstructor(name, a, b){ // super equivalent... // -// Example: // superMethod(, ).call(this, ...) // -> // @@ -101,6 +200,7 @@ function superMethod(cls, meth){ } + /********************************************************************** * vim:set ts=4 sw=4 : */ return module })