Is this a good pattern?

Objectives...

  • Remove vars, objects etc from the global object.
  • Remove possibility of collisions.
  • Firstly I implement the Yahoo namespace code (note for example purposes I am using ROOT as the root of my namespace)...

            if (typeof ROOT == "undefined" || !ROOT) {
                    var ROOT = {};
            }
    
            ROOT.namespace = function () {
                var a = arguments,
                    o = null,
                    i, j, d;
                for (i = 0; i < a.length; i = i + 1) {
                    d = ("" + a[i]).split(".");
                    o = ROOT;
                    for (j = (d[0] == "ROOT") ? 1 : 0; j < d.length; j = j + 1) {
                        o[d[j]] = o[d[j]] || {};
                        o = o[d[j]];
                    }
                }
                return o;
            }
    

    Now I declare my 1st namespace...

    ROOT.namespace("UI");
    
                ROOT.UI = {
                    utc: 12345,
                    getUtc: function() {
                        return this.utc;
                    }
                }
    

    What I want to do here is to hold vars that I need for my UI (in this case the current time in UTC) so that they are not on the global object. I also want to provide some specific functionality. This should be available on every page without any sort of instanciation...

    Now I want to have an object stored within my namespace structure. However, this object will need to be created multiple times. The objective here is to keep this inside my structure but allow it to be created as many times as I need. This is as follows:

     ROOT.namespace("AirportFinder");
                ROOT.AirportFinder = function(){ 
                    this.var1 = 99999;
    
                    this.Display = function() {
                        alert(this.var1);
                    }            
                }
    

    And this is the sample code to instanciate the object...

            var test1 = new ROOT.AirportFinder();
            test1.Display();
    

    Is this a good pattern?


    It is indeed reasonable to have things defined on a namespace ROOT or something alike.

    It's also better to use closures

    (function() {
        var AirportFinder = function() { 
            this.var1 = 99999;
            this.Display = function() {
                alert(this.var1);
            }            
        };
    
        // do Stuff with local AirportFinder here.
    
        // If neccesary hoist to global namespace
        ROOT.AirportFinder = AirportFinder;
    }());
    

    If they don't need to be global. I myself use an alias ( $.foobar because jQuery is global anyway) for storing any global data.

    I'm afraid I can't tell you waht the .namespace function does. It's not really neccessary.

    My personal preference is to always use closures to create a private namespace and hoist anything to the global/shared namespace where neccesary. This reduces the global visibility/cluster to a minimum.


    Slightly pointing you a little to the side, off the path of your question: Have a look at YUI3 (http://developer.yahoo.com/yui/3/) - you don't have (to have) anything in the global namespace there, you get a private sandbox. Great concept, I love that library and its conocepts (YUI3, not talking about old YUI2). The way it does that is of course simple and you could do that too: The dynamic module loader of YUI3 loads your module (.js file(s)), creates a sandbox (just a closure) and calls your callback, giving it a handle for the sandbox. No other code anywhere can gain access to that sandbox and your own names. Within that sandbox you can (and should) go on using the various encapsulation patterns. This YUI3 concept is great for mashups with foreign code, especially when mashups become more dynamic in nature (eg user triggered), instead of just integrating Google Maps or other well-known APIs by the programmers themselves.


    I tried to do a similar thing:

    var namespace = function(str, root) {
        var chunks = str.split('.');
        if(!root)
            root = window;
        var current = root;
        for(var i = 0; i < chunks.length; i++) {
            if (!current.hasOwnProperty(chunks[i]))
                current[chunks[i]] = {};
            current = current[chunks[i]];
        }
        return current;
    };
    
    // ----- USAGE ------
    
    namespace('ivar.util.array');
    
    ivar.util.array.foo = 'bar';
    alert(ivar.util.array.foo);
    
    namespace('string', ivar.util);
    
    ivar.util.string.foo = 'baz';
    alert(ivar.util.string.foo); 
    

    Try it out: http://jsfiddle.net/stamat/Kb5xY/

    Blog post: http://stamat.wordpress.com/2013/04/12/javascript-elegant-namespace-declaration/

    链接地址: http://www.djcxy.com/p/95302.html

    上一篇: JavaScript保证对象属性顺序?

    下一篇: 这是一个很好的模式?