1
\$\begingroup\$

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
Quill
12k5 gold badges41 silver badges93 bronze badges
asked Mar 26, 2013 at 16:20
\$\endgroup\$
2
  • 5
    \$\begingroup\$ Consider putting the opening { in the same line as the statement, e.g. var foo = {. When using return you are actually required to do this so it's a good idea to do it in any case. \$\endgroup\$ Commented Mar 26, 2013 at 16:24
  • \$\begingroup\$ Agreed. You shouldn't use curly-brace-on-new-line style in JavaScript. In other languages people can argue over style preferences forever, but in JavaScript things may simply break if you use brace-on-new-line style. So the debate will at least be shorter :) \$\endgroup\$ Commented Mar 26, 2013 at 18:00

1 Answer 1

4
\$\begingroup\$

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

answered Mar 27, 2013 at 3:05
\$\endgroup\$
1
  • \$\begingroup\$ thank you very much Joseph! looks very very smooth and has a excellent structure! thanks a lot! \$\endgroup\$ Commented Mar 28, 2013 at 16:41

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.