10

I have a question: What´s the better approach to limit the scope in Javascript: Using a namespace like this:

var NAMESPACE = {};
NAMESPACE.foo = function() { 
   console.log('Hello');
}
NAMESPACE.foo();

or should I use the self-invoking function like this

(function() {
    function foo() { console.log('Hello'); }
    foo();
})();

Is it always good to have a namespace or can I omit it if I just use one big self-invoking function where I put all my stuff?

Keen
  • 141
  • 7

4 Answers4

7

Both of your code samples have very different applications.

NAMESPACE.foo = function(){} and (function(){})() are both function expressions and (just as function declarations) delimit the inner scope and have access to vars/functions in their outer scopes.

The main difference is, with the namespace you can call the function anywhere that is in the same scope as the namespace, while the IIFE will only be executed when encountered.

There is no "best practice" without context, so I'll give some examples:

  • If your function expression is supposed to only execute once, an IIFE will do the job very well while a namespace will take some memory until it is garbage collected.
  • If your function expression will run multiple times (e.g. inside a for loop), an IIFE will cause a performance loss (and is not recommended by JSLint, or anyone in fact). It's better to have a defined function object which you call multiple times than creating a new function object for each iteration.
  • Ultimately, it depends on your user case. IIFEs are executed when encountered (e.g. Program/Function Body, IF Block etc.), while a namespace will store the function object and allow you to call it whenever you need, provided it is accessible in the given scope.

Reading material

Community
  • 1
  • 1
Fabrício Matté
  • 69,329
  • 26
  • 129
  • 166
3

What I tend to do is combine the two. I'm not sure whether this is considered best practice but it works for me :)

var app = { }; //or whatever your namespace is  

(function(){

app.memberA = {
   init: function() { },
   anotherFunction: function() { }
   // ...
};

})();

(function(){

app.memberB = {
   init: function() { }
   // So on...
};

})();

members A and B would be defined in separate js resource files - bundled and minified for production! I find this gives a nice separation of concerns when building OO JS.

Simon
  • 2,810
  • 2
  • 18
  • 23
0

Using a namespace puts something into the global scope.

Wrapping everything in a function and using only locally scoped variables doesn't.

The latter is clearly better for limiting scope.

Use a namespace if you need to expose parts of your code to other code in the page (which is typical for libraries). Define all the pieces of it inside a function though, as that reduces the chance of data escaping into global and gives you a closure for shared, private data in the namespace.

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
0

You should wrap all your code in a self-invoking function, and if you need to share some functionality with other parts of the app, assign those methods to your custom namespace. That way you only expose exactly what you need to.

armen.shimoon
  • 6,303
  • 24
  • 32