views:

14492

answers:

9

What neat ways do you use for declaring JavaScript namespaces. I've come across this one:

if (Foo == null || typeof(Foo) != "object") { var Foo = new Object();}

Is there a more elegant or succinct way of doing this?

Just a bit of fun...

+27  A: 

I like this:

var yourNamespace = {

    foo: function() {
    },

    bar: function() {
    }
};

...

yourNamespace.foo();
dfa
The important point is to be religious about expanding no further than the one root variable. *Everything* must flow from this.
annakata
Also, don't forget the commas between properties, e.g. between the "}" and "bar" in this example.
Bungle
The syntax of this approach really bothers me. I hate not ending lines with a semicolon and in this solution declaration order matters. I do still think it's a completely valid and in cases a good solution. How do you do callback functions on a JQUery call with this approach?
Chris
You'd also need a semicolon `;` after the yourNamespace declaration.
richard
+3  A: 

or try this approach:

http://weblogs.asp.net/mschwarz/archive/2005/08/26/423699.aspx

dfa
Explained very well about how to register namespace and how to attach libraries to namespace
pramodc84
+2  A: 

I use this approach:-

var myNamespace = {}
myNamespace._construct = function()
{
    var staticVariable = "This is available to all functions created here"

    function MyClass()
    {
       //Depending on the class may build all the class here
       this.publicMethod = function()
       {
          //Do stuff
       }
    }
    //Alternatively may use prototype
    MyClass.prototype.altPublicMethod = function()
    {
        //Do stuff
    }

    function privateStuff()
    {
    }

    function publicStuff()
    {
       //code that may call other public and private functions
    }

    //List of things to place publically
    this.publicStuff = publicStuff
    this.MyClass = MyClass
}
myNamespace._construct()

//The following may or may not be in another file
myNamespace.subName = {}
myNamespace.subName._construct = function()
{
   //build namespace
}
myNamespace.subName._construct()

External code can then:-

var myClass = new myNamespace.MyClass();
var myOtherClass = new myNamepace.subName.SomeOtherClass();
myNamespace.subName.publicOtherStuff(someParameter);
AnthonyWJones
Great detail! Thanks! Just wondering what's your take on Namespace.js. I've never used it myself, so I'm wondering if someone with your knowledge/skill/experience would consider using it.
John
+13  A: 

Another way to do it, which I consider it to be a little bit less restrictive than the object literal form, is this:

var ns = new function() {

    var internalFunction = function() {

    };

    this.publicFunction = function() {

    };
};

The above is pretty much like the module pattern and whether you like it or not, it allows you to expose all your functions as public, while avoiding the rigid structure of an object literal.

Ionuț G. Stan
It's kind of blindsided me that anyone wouldn't love OLN. I just... what's not to love? What's so rigid?
annakata
1. There's a difference between OLN and the module pattern.2. I don't /always/ like OLN as you have to remember to not put the last trailing comma and all your attributes must be initialized with a value (like null or undefined). Also, if you need closures for member functions, you will need small function factories for each of those methods. Another thing is that you must enclose all your control structures inside functions, whereas the above form does not impose that.That's not to say that I don't use OLN, is just that sometimes I don't like it.
Ionuț G. Stan
this style is compatible with my javascript editor (eclipse), as in, it can do auto formatting and indentation.
Titi Wangsa bin Damhore
I like this approach because it allows for private functions, variables, and pseudo-constants (i.e. var API_KEY = 12345;).
Lawrence Barsanti
+3  A: 

http://github.com/smith/namespacedotjs

You gotta check that out!! :D

The link is dead; can you find another one for NS.JS?
Will
Found it, and fixed the answer... and then noticed Rudy's answer below, which gives a lot more information: http://stackoverflow.com/questions/881515/javascript-namespace-declaration/3588712#3588712
StriplingWarrior
+1  A: 

After porting several of my libraries to different projects, and having to constantly be changing the top level (statically named) namespace, I've switched to using this small (open source) helper function for defining namespaces.

global_namespace.Define('startpad.base', function(ns) {
    var Other = ns.Import('startpad.other');
    ....
});

Description of the benefits are at my blog post. You can grab the source code here.

One of the benefits I really like is isolation between modules with respect to load order. You can refer to an external module BEFORE it is loaded. And the object reference you get will be filled in when the code is available.

mckoss
I've created an improved version (2.0) of the namespace library:http://code.google.com/p/pageforest/source/browse/appengine/static/src/js/namespace.js
mckoss
+5  A: 

Is there a more elegant or succinct way of doing this?

yes it is:

var your_namespace = your_namespace || {};

then you can have

var your_namespace = your_namespace || {};
your_namespace.Foo = {toAlert:'test'};
your_namespace.Bar = function(arg) 
{
    alert(arg);
};
with(your_namespace)
{
   Bar(Foo.toAlert);
}
Alex Pacurar
+2  A: 

I created namespace which is inspired by Erlang's modules. It is a very functional approach, but that is is how I write my js these days.

It gives a closure a global namespace and exposes a defined set functions within that closure.

(function(){

  namespace("images", previous, next);
  // ^^ this creates or finds a root object, images, and binds the two functions to it.
  // It works even though those functions are not yet defined.

  function previous(){ ... }

  function next(){ ... }

  function find(){ ... } // a private function

})();
The Who
+5  A: 

This is a follow-up to user106826's link to Namespace.js. It seems the project moved to github. The new link is now:

http://github.com/smith/namespacedotjs

I have been using this simple js helper for my tiny project and so far it seems to be light yet versatile enough to handle namespacing and loading modules/classes. It would be great if it would allow me to import a package into a namespace of my choice, not just the global namespace... sigh, but that's besides the point.

It allows you to declare the namespace then define objects/modules in that namespace:

Namespace('my.awesome.package'); 
my.awesome.package.WildClass = {};

Another option is to declare the namespace and it's contents at once:

Namespace('my.awesome.package', {
    SuperDuperClass: {
        saveTheDay: function() {
            alert('You are welcome.');
        }
    }
});

For more usage examples, look at the example.js file in the source: http://github.com/smith/namespacedotjs/blob/master/example/sandbox.js

Rudy Lattae