oop - Structuring a JavaScript app using a modular approach -
i trying write javascript application of sufficient size modularity idea. using famous inherit function enable objects inherit constructors have parameters. problem error parent being passed inherit function undefined. because, well, parent constructor hasn't been defined when inherit called.
i have come few ugly solutions problem:
declare child constructors after parent (yuk).
bind prototype assignments custom event , use ordered callback chain ensure prototypes assigned in order (perhaps there potential there).
move prototype assignments area in code constructor lives , consolidate (and exile) them 'assign prototypes' function (twice yuk of item one, no?).
the bottom line don't want have base order in constructors, methods, , objects written in code on order in code loaded/interpreted. want code extensible , related code grouped easy understand (i.e., shouldn't prototype assignment near constructor declaration/definition?).
i placing modules in separate files , using php script append them before sent browser. php script ensures file declares namespace included first, after concatenates js files glob.
i wrote little script demonstrates issue having. is live @ url. screen white because there no html — using console analysis here.
/*global console, jquery, $, myns: true*/ /*jslint browser: true*/ /* * file deliberately set first file in php glob. */ var myns = (function (myns, $, window, undefined) { "use strict"; /* * @param {object} coords -- e.g. {x: 3, y: 26} */ myns = function (coords) { return new myns.cartesianloc(coords); }; // static methods myns.inherit = function (parent) { function f() {} f.prototype = parent.prototype; return new f(); }; myns.getwincenter = function () { return { x : $(window).width() / 2, y : $(window).height() / 2 }; }; // prototype myns.prototype = { log: function () { if (window.console) { console.log(this); } } }; return myns; }(myns, jquery, window)); /* * file. */ (function (myns, $, window, undefined) { "use strict"; /* * cartesianloc constructor * * @param {object} coords -- given in conceptual * cartesian space origin (0,0) * middle of whatever screen */ function cartesianloc(coords) { myns.loc.call(this, coords); } cartesianloc.prototype = myns.inherit(myns.loc); cartesianloc.prototype.constructor = cartesianloc; cartesianloc.prototype.getwincoords = function () { return { x: myns.getwincenter().x + this.x, y: myns.getwincenter().y + this.y }; }; myns.cartesianloc = cartesianloc; }(myns, jquery, window)); /* * file. */ (function (myns, $, window, undefined) { "use strict"; // location constructor function loc(coords) { this.x = coords.x; this.y = coords.y; } loc.prototype = myns.inherit(myns); loc.prototype.constructor = loc; loc.prototype.translate = function (coords) { this.loc.x += coords.x; this.loc.y += coords.y; return this; }; myns.loc = loc; }(myns, jquery, window)); /* * application js file * */ (function (myns, $, window, undefined) { "use strict"; $(document).ready(function (event) { if (console) { console.log("%o", new myns({x: 100, y: -45})); } }); }(myns, jquery, window)); thanks or ideas can give me!
chris
i not sure whether sound practice or messy, created custom event triggers on document.ready , placed code assigns prototypes in callbacks event. know adding event fires when event fired (which seems pointless @ face), want custom event 1 listened in case want change way triggered later.
/*global console, jquery, $, myns: true*/ /*jslint browser: true*/ /* * file deliberately set first file in php glob. */ var myns = (function (myns, $, window, undefined) { "use strict"; /* * @param {object} coords -- e.g. {x: 3, y: 26} */ myns = function (coords) { return new myns.cartesianloc(coords); }; // triggered after constructors have been defined $(document).ready(function (event) { $(document).trigger("myns"); }); // static methods myns.inherit = function (parent) { function f() {} f.prototype = parent.prototype; return new f(); }; myns.getwincenter = function () { return { x : $(window).width() / 2, y : $(window).height() / 2 }; }; // prototype myns.prototype = { log: function () { if (window.console) { console.log(this); } } }; return myns; }(myns, jquery, window)); /* * file. */ (function (myns, $, window, undefined) { "use strict"; /* * cartesianloc constructor * * @param {object} coords -- given in conceptual * cartesian space origin (0,0) * middle of whatever screen */ function cartesianloc(coords) { myns.loc.call(this, coords); } $(document).on('myns', function (event) { cartesianloc.prototype = myns.inherit(myns.loc); cartesianloc.prototype.constructor = cartesianloc; cartesianloc.prototype.getwincoords = function () { return { x: myns.getwincenter().x + this.x, y: myns.getwincenter().y + this.y }; }; }); myns.cartesianloc = cartesianloc; }(myns, jquery, window)); /* * file. */ (function (myns, $, window, undefined) { "use strict"; // location constructor function loc(coords) { this.x = coords.x; this.y = coords.y; } $(document).on('myns', function (event) { loc.prototype = myns.inherit(myns); loc.prototype.constructor = loc; loc.prototype.translate = function (coords) { this.loc.x += coords.x; this.loc.y += coords.y; return this; }; }); myns.loc = loc; }(myns, jquery, window)); /* * application js file * */ (function (myns, $, window, undefined) { "use strict"; $(document).ready(function (event) { if (console) { console.log("%o", new myns({x: 100, y: -45})); } }); }(myns, jquery, window));
Comments
Post a Comment