Are there any dangers associated with using JavaScript namespaces?

爷,独闯天下 提交于 2019-12-05 12:02:53

The way you define namespaces in your example it appears to create globals out of each namespace so you end up with

window.namespace1
window.namespace2
window.globalNamespace
window.globalNamespace.namespace1
window.globalNamespace.namespace2

So if you have anything that clobbers window.namespace1 it will also clobber window.globalNamespace.namespace1

edit:

Here's how we got around this problem:

namespacing = {
    init: function(namespace) {
        var spaces = []; 
        namespace.split('.').each(function(space) {
            var curSpace = window,
                i;  

            spaces.push(space);
            for (i = 0; i < spaces.length; i++) {
                if (typeof curSpace[spaces[i]] === 'undefined') {
                    curSpace[spaces[i]] = {}; 
                }   
                curSpace = curSpace[spaces[i]];
            }   
        });
    }
};

Then you use it like this:

namespacing.init('globalNamespace.namespace1');

globalNamespace.namespace1.doSomething = function() { ... };

This way you don't have to introduce new global variables and you can confidently add to an existing namespace without clobbering other objects in it.

Since you are basically adding functions to objects and those objects into other objects, I would expect each browser to handle this the same way.

But if you want modularity, why not use a (relatively) simple framework like require.js? That will allow you and your team to write code in a modular fashion and allows the team to 'import' these modules where needed:

require(["helper/util"], function() {
  //This function is called when scripts/helper/util.js is loaded.
});

Require.js will take care of dependencies, and it will also prevent polluting the global namespace.

We use a similar system at work and it does the job just fine. I don't see any drawbacks there could be; it's just objects and properties. For that same reason, cross browser compatibility should be good. You can end up having to write some long names to resolve to a particular function, like Foo.Bar.Test.Namespace2.Function, but even then that can be solved by assigning it to a variable before hand.

This is how I'd recommend doing it, so you stay out of the global scope entirely except for your "base" namespace. We do something similar where I work. Let's say you work for Acme co, and want ACME to be your base namespace.

At the top of every file, you'd include:

if (!window.ACME) { window.ACME = {} }

Then you just go and define whatever you want in terms of that.

ACME.Foo = {
  bar: function () { console.log("baz"); }
}

If you want a deeper level of namespace, you just do the same thing for each level.

if (!window.ACME) { window.ACME = {} }
if (!ACME.Foo) { ACME.Foo = {} }

This way each file can be tested independently and they'll set up the namespace infrastructure automatically, but when you compile them together or if you test multiple files simultaneously, they won't keep overwriting things that are already defined.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!