JavaScript Namespace

后端 未结 11 1396
暗喜
暗喜 2020-12-15 07:25

I want to create a global namespace for my application and in that namespace I want other namespaces:

E.g.

Dashboard.Ajax.Post()

Dashboard.RetrieveC         


        
相关标签:
11条回答
  • 2020-12-15 07:47

    There are several libraries that already offer this sort of functionality if you want to use or examine a pre-baked (that is, a tested) solution.

    • YUI.attribute and YUI.base
    • dojo.mixin
    • underscore.extend
    • jQuery.extend
    • goog.provide and goog.object.extend

    The simplest and most bug free one to get going with is probably jQuery.extend, with the deep argument set to true. (The reason I say it is bug free is not because I think that jQuery.extend suffers from less bugs than any of the other libraries -- but because it offers a clear option to deep copy attributes from the sender to the receiver -- which most of the other libraries explicitly do not provide. This will prevent many hard-to-diagnose bugs from cropping up in your program later because you used a shallow-copy extend and now have functions executing in contexts you weren't expecting them to be executing in. (If however you are cognizant of how you will be extending your base library while designing your methods, this should not be a problem.)

    0 讨论(0)
  • 2020-12-15 07:47

    Implementation:

    namespace = function(packageName)
    {
        // Local variables.
        var layers, layer, currentLayer, i;
    
        // Split the given string into an array.
        // Each element represents a namespace layer.
        layers = packageName.split('.');
    
        // If the top layer does not exist in the global namespace.
        if (eval("typeof " + layers[0]) === 'undefined')
        {
            // Define the top layer in the global namesapce.
            eval(layers[0] + " = {};");
        }
    
        // Assign the top layer to 'currentLayer'.
        eval("currentLayer = " + layers[0] + ";");
    
        for (i = 1; i < layers.length; ++i)
        {
            // A layer name.
            layer = layers[i];
    
            // If the layer does not exist under the current layer.
            if (!(layer in currentLayer))
            {
                // Add the layer under the current layer.
                currentLayer[layer] = {};
            }
    
            // Down to the next layer.
            currentLayer = currentLayer[layer];
        }
    
        // Return the hash object that represents the last layer.
        return currentLayer;
    };
    


    Result:

    namespace('Dashboard.Ajax').Post = function() {
        ......
    };
    
    namespace('Dashboard.RetrieveContent').RefreshSalespersonPerformanceContent = function() {
        ......
    };
    


    Gist:

    namespace.js

    0 讨论(0)
  • 2020-12-15 07:48

    The Yahoo Namespace function is exactly designed for this problem.

    Added:

    The source of the function is available. You can copy it into your own code if you want, change the root from YAHOO to something else, etc.

    0 讨论(0)
  • 2020-12-15 07:53

    With the NS object created, you should just be able to add to it from where ever. Although you may want to try var NS = NS || {}; to ensure the NS object exists and isn't overwritten.

    // NS is a global variable for a namespace for the app's code
    var NS = NS || {};
    
    NS.Obj = (function() {
    
      // Private vars and methods always available to returned object via closure
      var foo; // ...
    
      // Methods in here are public
      return {
        method: function() {
    
        }
      };
    
    }());
    
    0 讨论(0)
  • 2020-12-15 07:55

    bob.js can help in defining your namespaces (among others):

    bob.ns.setNs('Dashboard.Ajax', {
    
        Post: function () { /*...*/ }
    });
    
    bob.ns.setNs('Dashboard.RetrieveContent', {
    
        RefreshSalespersonPerformanceContent: function () { /*...*/ }
    });
    
    0 讨论(0)
  • 2020-12-15 07:58

    You just need to make sure that you don't stomp on your namespace object if it's already been created. Something like this would work:

    (function() {
        // private vars can go in here
    
    
        Dashboard = Dashboard || {};
        Dashboard.Ajax = {
            Post: function() {
                ...
            }
        };
    })();
    

    And the RetrieveContent file would be defined similarly.

    0 讨论(0)
提交回复
热议问题