Namespacing
1) Is it good enough that I am splitting my functions and then adding them to a single global object? Any better way?
Yes, it's a good and popular approach. It's simple and it works.
You might consider using closures to create app.p
, app.q
and app.r
. I think this is referred to as using IIFEs (immediately invoked function expressions) [details]. Right now, app.p
, app.q
and app.r
have no persistent private scope. The only private scope they will have is whatever happens within the function, itself. If they needed to keep track of something, they will need to use a variable in the global scope because it is the only scope outside of the function. Using an 'IIFE' would allow there to be some persistent and private state for each function:
app.p = (function() {
var someCounter = 0;
return function(){
someCounter++;
// do stuff
}
})();
Now, app.p
can access the someCounter
variable but nothing else can. Some people don't care for this, but I'm a fan.
For larger projects, the var app = app || {};
might become unwieldy. Something I've been working with a bit that allows a little more flexibility is at the bottom of this page:
http://elegantcode.com/2011/01/26/basic-javascript-part-8-namespaces/
function namespace(namespaceString) {
var parts = namespaceString.split('.'),
parent = window,
currentPart = '';
for(var i = 0, length = parts.length; i < length; i++) {
currentPart = parts[i];
parent[currentPart] = parent[currentPart] || {};
parent = parent[currentPart];
}
return parent;
}
Using this approach, to define something in a namespace (modified from the same page):
// using an immediately invoked function expression (IIFE)
// keeps things private to the function and prevents spillage
// of variables into this outer scope
(function() {
// retrieve what exists or make a new definition
var examples = namespace('io.examples');
// add something to it (another IIFE)
examples.log = (function() {
// can have private variables
var numMsgs = 0,
// for this, the api is an invokable function: api(), but
// we will also add more functions to it: api.subFunction()
// these will all have access to the numMsgs private variable
api = function() {
numMsgs++;
console.log.apply(console, arguments);
};
api.getMsgCount = function() {
return numMsgs;
}
// returning api sets io.examples.log to the api function
return api;
})();
})();
And, to use something from a namespace:
// retrieve what exists (we already made something,
// so it will not create an empty place-holder)
var log = namespace('io.examples.log');
// the api was a function, so we can call it
// or access the sub-function we attached to it
log('hello');
var numSoFar = log.getMsgCount();
A related topic is AMDs (asynchronous module definitions) and dependency-injection (which is rather a sub-set of what AMDs set out to do, I think). Some options are requireJS, yepnope, and angularjs (which entails committing the project to the angularjs framework). I'm sure there are a lot of others, I just don't know them.
native addEventListener
2) I am using some native window.addEventListener() calls...
Historically, when I avoid using a library it's because I don't want to either load it. That being said, the performance difference is impressive. Most things I write are driven from UI events, which are generally rare (how often are you clicking?), and the performance difference between the two doesn't matter. I would say it doesn't even matter if the code base is large. Seems like the main thing would be whether you are handling events that occur super-frequently or not.
It's also worth noting that creating a dependency on a library can hinder the reusability of whatever you're writing.
init process
3) How the whole execution begins, like Zepto kickstarts init() function
If you're using native event listeners, then you don't have a choice, it can't go in the Zepto init. If you're using the Zepto init process, I would just put it in the Zepto(...)
if a) nothing else needs a reference to it and b) you don't need it before then, anyway.