4

My code is going to turn into a mess if I don't start using some sort of namespacing technique. I'm relatively new to programming large javascript projects but have significant experience with systems programming in C++/java/python etc.

Basically I'm trying to identify which is the preferred method for creating javascript namespaces, and what the pros/cons are for each method.

For example I could use either of the following three methods:

var proj.lib.layout = {
  "centreElem":     
  function (elem, W, H){

  },

  "getAbsolutePosition":
  function (elem){

  }
};

OR

var proj.lib.layout = {};
(function(){
  var l = proj.lib.layout;

  l.centreElem = function (elem, winW, winH){
    ..
  }

  l.getAbsolutePosition = function (elem){
    ..
  }
})();

OR

var proj.lib.layout = new function(){
  function centreElem(elem, W, H){
    ..
  }

  function getAbsolutePosition(elem){
    ..
  }

  this.centreElem          = centreElem;
  this.getAbsolutePosition = getAbsolutePosition;
} ();

There are other ways to do it too obviously, but these were the first that I've seen and thought of. Can anyone say there is a "best" technique, or at least point me towards some pros/cons from which I can evaluate which is best for me?

rewolf
  • 5,561
  • 4
  • 40
  • 51
  • possible duplicate of [Javascript Namespace Declaration](http://stackoverflow.com/questions/881515/javascript-namespace-declaration) – jball Jul 01 '11 at 15:02

4 Answers4

3

Note that you have to create all the intermediary objects before you can assign to a sub-object like that:

window.one.two.three = {}; // fails
window.one = { two: { three: {} } };

Consider writing a namespacing method, so you can unify your namespace code. For example:

window.proj = {};
// n - {String} - A string representing a namespace to create on proj
// returns an object you can assign values to
window.proj.namespace = function(n) { /* ... */ };

(function(NS) {
    NS.myMethod = function() {};
    NS.myOtherMethod = function() {};
    NS.myProperty = "FOO";
})(proj.namespace('lib.layout'));

assert(proj.lib.layout.myProperty === "FOO");
Nick Husher
  • 1,909
  • 11
  • 13
  • I was confused at first about what you meant by the `namespace()` function, but I now it's meant to perform the generic creation of namespaces such as setting up of intermediary namespaces. Good idea and thanks. I assume then that you approve and recommend that form of namespace declaration (the self-executing anonymous function). – rewolf Jul 01 '11 at 18:34
  • As an aside, this is generically referred to as the "module pattern" in the Javascript universe. – Nick Husher Jul 04 '11 at 04:23
  • Also, I had considered including a namespace function implementation, but it's a reasonably common framework function. The basic algorithm is to split on ".", loop through the pieces, create the necessary intermediate objects. Finally, return a reference to the last object created. – Nick Husher Jul 04 '11 at 04:30
1

My preferred method is to have a single object (whose name is usually short, 2-3 characters, and all upper-case) as my namespace in which to contain all other objects.

The method shown below (which corresponds most closely with your second example) also shows how to hide any private functions:

// In this example the namespace is "QP"
if (!QP) {
    var QP = {};
};

// Define all objects inside an closure to allow "private" functions
(function() {

     QP.examplePublicFunction = function() {
         ...
     }

     function examplePrivateFunction() {
         ...
     }

})();

This is the method used by a number of other JavaScript libraries, for example json2.js

I've never really felt the need to subdivide my namespaces into subnamespaces.

Justin
  • 84,773
  • 49
  • 224
  • 367
0

Basically all three examples use the same "namespace" technique, that is, create a basic object (your namespace) and then augment it with your functions.

usually the root namespace is in capital letters:

if (typeof (MYAPP) == "undefined" || !MYAPP) {
    var MYAPP= {}
};

Then you can add functionality to this base object in various ways. In your code you show three of them, but each of them end up with the same result, you can call this two functions:

proj.lib.layout.centreElem(elem, W, H);
proj.lib.layout. getAbsolutePosition(elem);
Matt
  • 4,462
  • 5
  • 25
  • 35
Nicola Peluchetti
  • 76,206
  • 31
  • 145
  • 192
0

The Google Closure Javascript Library uses this style (which is not exactly like any of your examples)

goog.math.clamp = function(value, min, max) {
  return Math.min(Math.max(value, min), max);
};

I would stick with this simple style. Don't bother with self-executing anonymous function wrappers. The one in your example doesn't actually do anything useful.

Peter Lyons
  • 142,938
  • 30
  • 279
  • 274
  • Yeah, I was doing that to avoid having to type the full chain for each function. And putting it in a self-executing function meant that the temporary l wouldn't exist globally. Its also marginally faster, i'd assume as you don't have to traverse the chain during assignment, and the function bodies that reference variables/functions within the same namespace don't need to specify the chain either. – rewolf Jul 01 '11 at 18:28