I have the following example app: http://dev.driz.co.uk/jsfunction/
Which runs two types of script files with the same outcome.
Script1:
var script1 = {
showMessage: function( message ) {
var el = document.getElementById('example1');
el.innerHTML = message;
}
}
and script 2:
window.script2 = function() {
function showMessage( message ) {
var el = document.getElementById('example2');
el.innerHTML = message;
}
return {
showMessage: showMessage
}
}();
They are both namespaced so I can them like:
window.onload = function() {
script1.showMessage('Hello world!');
script2.showMessage('How are you?');
};
But what's the better way forward? Script1 is the type I would normally write but it requires you to sometimes call a init function first if you have some events that need running on document load.
For example:
var script = {
init: function() {
// some events such as onlick etc..
}
};
script.init();
Script2 however is a self executing function and therefore would get around this but being a function itself would it allow the same flexibility?
Any thoughts? Suggestions or examples of how people namespace there script files to make them neater and more efficient?
2 Answers 2
Try module-pattern, or somewhat like the module pattern, using an IIFE
In your case:
(function(ns){
ns.showMessage = function(message){
var el = document.getElementById('example1');
el.innerHTML = message;
}
}(this.script1 = this.script1 || {}));
window.onload = function() {
script1.showMessage('Hello world!');
};
Here's the explanation
//basically, an IIFE is a function that executes itself
(function(ns){
//in here, ns is a reference to our this.namespace
//also, this IIFE provides us with a local scope
//we can declare functions and variables that only this scope, by default, sees
//a "private" variable
var priv = "I can only be seen in the module";
//a "private" function
function privFn(){
console.log('I am only usable in the module');
}
//a "public", or more accurately, an "exposed" variable
//we attach it to the namespace
ns.foo = 'I am an exposed value';
//an exposed function
ns.bar = function(){
console.log('exposed!');
//with an exposed function, we can also call a private function
privFn();
}
//this line creates the namespace or uses an existing one
//it then executes the function, passing the created/existing namespace
}(this.namespace = this.namespace || {}));
And so, using our module:
//we can use the exposed entities
namespace.bar();
//exposed!
//I am only usable in the module <- since bar called privFn, it also prints
namespace.foo === 'I am an exposed value'
I think it depends on what you need.
For script1
, every end point can be accessed. this
can be referenced as the object. I like the pattern like:
var Car = {
name: null,
init: function (name) {
this.name = name;
}
};
For script2
, it encapsulates some private variables or functions, which cannot be accessed outside of the anonymous function scope. You can choose what to expose and what to hide.
var Car = (function () {
var MAX_SPEED = 120; //cannot be referenced
function init() {
//something cannot be referenced outside the Car
}
function run() {
//...
}
return {
run: run;
};
})();
These are the ways to create simple namespaces. Because you can also make namespace into a module.
namespace("GLOBAL.app.Ticker");
namespace
will be a simple module to parse the string GLOBAL.app.Ticker
, and convert it to a new Object.