How can I create an empty namespace object without overwriting another object with the same name?

前端 未结 3 1573
南旧
南旧 2021-01-23 10:51

I have been studying as much as I can about the Module Pattern suggested by the Yahoo YUI Blog.

I\'ve noticed that the YUI offers the ability to create a new empty names

相关标签:
3条回答
  • 2021-01-23 11:24

    In your example, it could work like this:

    if (!YAHOO.myProject) {
        YAHOO.myProject = {};
    }
    YAHOO.myProject.whatever = true;
    

    or using your own parent module name:

    var myModule = myModule || {};  // make sure parent is defined without overwriting
    if (!myModule.myProject) {
        myModule.myProject = {};
    }
    myModule.myProject.whatever = true;
    

    Or define your own namespace function:

    function myNamespace(item) {
        if (!myModule[item]) {
            myModule[item] = {};
        }
    }
    
    myNamespace("myProject");
    myNamespace.myProject.whatever = true;
    
    0 讨论(0)
  • 2021-01-23 11:32

    Q. How can I create an empty namespace object without overwriting another object with the same name?

    You can't. By definition the same name can't refer to both your new empty object and an existing object.

    If you mean "How can I check create an empty namespace object only if it doesn't already exist, otherwise I want to add to the existing one", then you just do this:

    if (!YAHOO.myProject)
       YAHOO.myProject = {};
    
    // or you may see this variation:
    YAHOO.myProject = YAHOO.myProject || {};
    

    I don't like the latter but it is used frequently to achieve the same effect as a plain if statement.

    To take this general principle much further have a look at this article: http://www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth

    UPDATE: According to the YUI API documentation for YAHOO.namespace(), the method "Returns the namespace specified and creates it if it doesn't exist" - which you'll note is much less ambiguous than the wording of the blog you were reading, and pretty much backs up what I already said...

    0 讨论(0)
  • 2021-01-23 11:40

    Edit Just realized I'm not directly answering your question. Sorry! However hopefully this will help you understand some alternate techniques.

    This is a technique I use from time to time, such as when I want to add a property or function once and not allow it to be overwritten later.

        var module = new function(){
    
            var modules = {}; //internal module cache
    
            return function(name, module){
                //return all modules
                if( !name ) return modules;
    
                //return specific module
                if( modules[name] ) return modules[name];
    
                //return the module and store it
                return modules[name] = module;
            }
    
        }
    

    So you can use it like so:

    //will store this since it doesn't exist
    module('test', 'foo'); //Since 'test' doesn't exist on the internal 'modules' variable, it sets this property with the value of 'foo'
    
    module('test'); // Since we aren't passing a 2nd parameter, it returns the value of 'test' on the internal 'modules' variable
    
    module('test', 'bar'); //We are attempting to change the value of 'test' to 'bar', but since 'test' already equals 'foo', it returns 'foo' instead.
    
    module(); // { 'test': 'foo' } //Here we aren't passing any parameters, so it just returns the entire internal 'modules' variable. 
    

    The key thing to look at is that we're using 'new function()'. This is done at assignment, because we really want 'module' to be the internal function, not the outer. But in order to create a closure for the internal 'var modules' variable, the outer function has to execute on assignment.

    Also notice that you could write the outer function to be self executing too:

    var module = function(){
        var modules = {};
        //other stuff
    }();
    
    0 讨论(0)
提交回复
热议问题