I have to set up a new JavaScript library for a big project, which isn't Object Oriented yet. So I built a small file to test some needs. The result is the following:
var Module =
{
Config: (function()
{
//- private members
var _systemName = 'mySystem',
_version = '1.1.4';
//- private methods
//...
//- public methods
var api =
{
getSystemInfo: function()
{
return "system: '"+_systemName+"' @ version "+_version;
}
};
return api;
})(),
Dialog:
{
_: (function(){
$(document).ready(function()
{
$('.showDialog').on('click',function()
{
var obj = {
element: this,
foo: 'foo',
bar: 'bar',
target: $('#title')
};
Module.Dialog.setParam(obj);
Module.Dialog.show();
})
});
})(),
setParam: function(config)
{
console.log('config set for dialog box');
console.log(config);
},
show: function()
{
console.log('dialogbox show | '+Module.Config.getSystemInfo());
},
close: function()
{
console.log('dialogbox close');
}
},
Savescreen:
{
setParam: function(config,foo)
{
console.log('config set for savescreen');
},
show: function()
{
console.log('savescreen show | '+Module.Config.getSystemInfo());
}
}
}
Goals:
- access via
Module.Object.Function()
- no instantiation via keyword new
- private members and methods (in config section or event-listner)
- easy structured and object orientated
- each section must have its own scope (section =
savescreen
,config
,dialogbox
, etc) - each section should hold its event-listner
1 Answer 1
To start off, your module should be the bare minimum, but extendable (like jQuery). That way, you won't have problems with scalability and maintenance. Here's a simple module template, where everything gets declared in the Module
namespace:
//this is a simple module declaration:
(function(Module){
//everything here is private unless attached to the Module namespace
var imPrivate = 'cant see me!';
//here's an example of an exposed functionality
Module.imaPublicProperty = 'public property here';
Module.imaPublicFunction = function(){
console.log('im public');
}
//here's an example privileged methods, public methods that have access
//to the private scope. These are your "setters and getters" in Java-speak
Module.imaPrivilegedFunction = function(){
console.log(imPrivate);
}
}(this.Module = this.Module || {}));
I suggest you build a helper function that actually appends your sections to your namespace. That way, the module would scale easily. Also, you don't have to fiddle with the base-code and lose commas along the way.
Here's a simple, yet incomplete implementation using this new approach (it lacks the document.ready part). It is long, yet it's modular and easily maintainable. You can even split the section codes in separate files.
(function (ns) {
ns.addSection = function (name, def) {
ns[name] = new def();
}
}(this.Module = this.Module || {}));
//adding config
Module.addSection('Config', function () {
var systemName = 'mySystem',
version = '1.1.4',
section = this;
section.getSystemInfo = function () {
return systemName + ' v' + version;
}
});
//adding Dialog
Module.addSection('Dialog', function () {
var section = this;
section.onDocumentReady = function () {
$('.showDialog').on('click', function () {
var obj = {
element: this,
foo: 'foo',
bar: 'bar',
target: $('#title')
};
section.setParam(obj);
section.show();
})
}
section.setParam = function (config) {
console.log('config set for dialog box');
console.log(config);
}
section.show = function () {
console.log('dialogbox show | ' + Module.Config.getSystemInfo());
}
section.close: function () {
console.log('dialogbox close');
}
});
//Savescreen section
Module.addSection('Savescreen', function () {
var section = this;
section.setParam = function (config, foo) {
console.log('config set for savescreen');
}
section.show = function () {
console.log('savescreen show | ' + Module.Config.getSystemInfo());
}
});
Here's how it's possibly used:
Module.Config.getSystemInfo();
//mySystem v1.1.4
So basically, you have base code and you just append to the namespace the sections via a helper function. Keeps the code clean and loose.
I suggest looking at KernelJS, which implements this pattern
-
\$\begingroup\$ thank you very much Joseph! looks very very smooth and has a excellent structure! thanks a lot! \$\endgroup\$roman– roman2013年03月28日 16:41:27 +00:00Commented Mar 28, 2013 at 16:41
{
in the same line as the statement, e.g.var foo = {
. When usingreturn
you are actually required to do this so it's a good idea to do it in any case. \$\endgroup\$