【问题标题】:What's the difference between these two approaches to namespacing?这两种命名空间方法有什么区别?
【发布时间】:2012-02-13 16:44:38
【问题描述】:

我的代码目录中的第一个文件如下

myNamespace.js

var myNamespace = {};

那么我后续的文件可以看成以下两种方式之一。

第一

(function (ns) {
    ns.DoStuff = function(){
        // do stuff
    }
})(myNamespace);

秒

myNamespace.DoStuff = function(){
    //do stuff
}

那么这两种方法有什么区别呢?两者似乎都对我有用。有更普遍接受的约定吗?

抱歉,javascript 还是新手

【问题讨论】:

    标签: javascript coding-style namespaces


    【解决方案1】:

    您的第一种方法行不通。它将在global object(很可能是window)上创建DoStuff。您需要将this 替换为ns,这样做之后,这两种方法之间就没有区别了。

    前者的好处是您可以将所有与应用程序/文件相关的内容关闭到外部自调用关闭函数中。所以你不会破坏全局命名空间。

    (function (ns) {
        var foo = 10,
            bar = 42;
    
        ns.DoStuff = function(){
            console.log('foo is ', foo, ' and its not available globally');
        }
    })(myNamespace);
    

    【讨论】:

    • 如何在仍然使用此方法的同时使变量全局可用?
    • @ChaseFlorell:实际上你不想那样做。将内容写入全局对象是 Javascript 中最糟糕/最危险的事情之一。但是,您始终可以从任何地方直接访问window.XXX = 42;。
    • 谢谢,我将发布一个与此问题分开的更详细的问题。我在这里得到了答案。
    【解决方案2】:

    你的第一个错误,你使用了this,我很确定你的意思是ns:

    ns.DoStuff = function() {
    };
    

    除此之外,您的第一种方法往往会更好,因为您为自己创建了一个不错的小范围函数,它允许您拥有私有数据和函数,可用于您在命名空间上创建的所有公共方法,而无需使它们成为全球性的。例如:

    (function(ns) {
        function privateFunction() {
        }
    
        ns.DoStuff = function() {
            privateFunction();   // <=== works fine
        };
    
    })(myNamespace);]
    privateFunction(); // <=== doesn't work, because it's private
    

    我喜欢这样做的部分原因是因为I have thing against anonymous functions,所以我不会像上面那样定义DoStuff,而是像这样:

    (function(ns) {
        ns.DoStuff = Namespace$DoStuff;
        function Namespace$DoStuff() {
        }
    })(myNamespace);
    

    现在我分配给myNamespace.DoStuff 的函数有了一个正确的名称,这可以在我调试代码时帮助我。但该名称不会污染全局命名空间,这有助于我保持清醒并避免与其他代码冲突。

    【讨论】:

    • 太棒了,谢谢。我根据this 错误编辑了我的问题。
    • 呃哦......你的编辑对我来说有点复杂:( - 你真的是指myNamespace$DoStuff吗?$ 符号在那个名字中代表什么?
    • @ChaseFlorell:名称可以是任何你想要的 --myNamespace$DoStuff、myNamespace_DoStuff、fred,等等。无论您想在调试器中的调用堆栈上看到什么。 :-) $ 并不重要,它只是标识符的有效字符。在我自己的工作中,我使用初始封顶的“命名空间”(通常;例如Nifty),并将约定 &lt;constructor&gt;$&lt;functionName&gt; 用于成为由构造函数创建的实例的属性的函数,并使用 &lt;namespace&gt;_&lt;functionName&gt; 用于将直接在命名空间上。 (而且我在上面应用了错误的!)
    猜你喜欢
    • 2013-09-08
    • 2019-03-31
    • 1970-01-01
    • 2020-02-14
    • 2011-01-10
    • 2016-07-01
    • 2013-08-08
    • 1970-01-01
    相关资源
    最近更新 更多