如何在不覆盖具有相同名称的另一个对象的情况下创建空命名空间对象?

时间:2012-02-24 05:38:10

标签: javascript methods namespaces yui javascript-namespaces

我一直在研究Yahoo YUI Blog建议的模块模式。

我注意到YUI提供了创建一个新的空命名空间对象的能力,而不会覆盖现有的同名名称,如下所示:

YAHOO.namespace("myProject");

然后可以调用它并与YAHOO.myProject

一起使用

(提醒:如果YAHOO.myProject已经存在,则不会被覆盖)

如何使用普通的javascript,而不使用YUI来实现类似的效果?

请尽可能详细地解释。

完整的YUI博客文章可以找到here

当我正在学习并加强我的javascript知识和技能时,我正在尝试创建自己的个人javascript库(即使我从不需要使用它)

3 个答案:

答案 0 :(得分:2)

在您的示例中,它可以像这样工作:

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

或使用您自己的父模块名称:

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

或者定义自己的命名空间函数:

function myNamespace(item) {
    if (!myModule[item]) {
        myModule[item] = {};
    }
}

myNamespace("myProject");
myNamespace.myProject.whatever = true;

答案 1 :(得分:1)

问。如何在不覆盖具有相同名称的其他对象的情况下创建空名称空间对象?

你做不到。根据定义,相同的名称不能同时引用新的空对象和现有对象。

如果你的意思是“我怎么能检查创建一个空的命名空间对象,只有它不存在,否则我想添加到现有的”,然后你就这样做了:

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

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

我不喜欢后者,但经常使用它来获得与普通if语句相同的效果。

要采用这个一般原则,很多进一步看看这篇文章:http://www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth

UPDATE:根据YUI API documentation for YAHOO.namespace(),方法“返回指定的命名空间,如果它不存在则创建它” - 你会注意到它比模糊的要少得多您正在阅读的博客的措辞,并且几乎支持我已经说过的内容......

答案 2 :(得分:1)

编辑刚刚意识到我没有直接回答你的问题。抱歉!但希望这有助于您了解一些替代技术。

这是我不时使用的一种技术,例如当我想要添加属性或函数一次而不允许稍后覆盖它时。

    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;
        }

    }

所以你可以像这样使用它:

//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. 

要注意的关键是我们正在使用'new function()'。这是在赋值时完成的,因为我们真的希望'module'是内部函数,而不是外部函数。但是为了为内部'var modules'变量创建一个闭包,外部函数必须在赋值时执行。

另请注意,您可以将外部函数编写为自执行:

var module = function(){
    var modules = {};
    //other stuff
}();