【问题标题】:Share a JavaScript library's namespace or use your own?共享 JavaScript 库的名称空间还是使用您自己的名称空间?
【发布时间】:2011-03-03 07:58:49
【问题描述】:

在 JavaScript 中众所周知,在全局范围内声明变量是一件坏事。所以我倾向于处理的代码包含命名空间的 JavaScript。

似乎有两种不同的方法来解决这个问题 -

  1. 将您的应用程序特定功能添加到库的命名空间,例如$.myCarouselfunction
  2. 创建自己的命名空间,例如MyApplication.myCarouselFunction

我想知道是否有更好的解决方案,或者他们是否倾向于在利弊方面接近。

到目前为止,我个人决定不使用该库的原因是分离/隔离/缺乏与库代码和可能共享该命名空间的潜在插件的冲突。还有其他我没有考虑的吗?

【问题讨论】:

    标签: namespaces javascript global-scope


    【解决方案1】:

    我个人喜欢这种方法:

    (function(namespace) {
    
    function myPrivateFunction(){};
    
    namespace.myPublicFunction = function(){};
    
    })($); // passing the $ namespace, but if it clutters, 
           // we can change it to something else
    

    【讨论】:

      【解决方案2】:

      如果您曾经尝试使用相同的命名空间引入多个库,那么发生冲突的可能性可能会令人惊讶,而且会令人非常沮丧,因为这些错误经常会以令人惊讶和难以调试的方式。我认为您对冲突的直觉是正确的,关于是定义自己的命名空间还是重用他人的命名空间,最重要的考虑是尊重命名空间的所有权。这意味着除非您与维护另一个命名空间的人保持联系并且他们知道您在做什么,否则最好使用您自己的命名空间。

      如果您决定忽略关于命名空间所有权的建议并在现有命名空间上定义 API(用于语义或其他),需要考虑的一件事是使用导出函数来检测错误。基本上,您可以先在自己的命名空间上定义一些东西,然后将其导出到目标命名空间,如下所示:

      MyApplication.exportName = function(objToExportTo, name, obj) {
        if (objToExportTo[name] === undefined) {
          objToExportTo[name] = obj;
        } else {
          // Possibly assert!
        }
      };
      
      MyApplication.myCarouselFunction = function() { ... };
      MyApplication.exportName($, 'myCarouselFunction', MyApplication.myCarouselFunction);
      

      【讨论】:

        【解决方案3】:

        我认为选择这类东西最重要的是语义

        您的函数/类是否扩展或依赖于特定于库的功能? 将其放在库命名空间中。

        你的函数/类库是独立的吗?在这种情况下,最好将它放在自定义命名空间中。这使得在您最初使用它的库之外重用您的代码成为可能。

        【讨论】:

        • 我同意,但请记住,使用命名空间可以避免潜在的名称冲突,尤其是在库更新之后,尤其是在您可以重新定义变量的 javascript 中,一切都会像什么都没发生一样继续进行。
        【解决方案4】:

        正确的选择取决于您的目标环境。您在两个命名空间之间进行选择,这两个命名空间都可能变得任意混乱。如果您认为更有可能在库命名空间中遇到冲突,则应使用窗口命名空间。如果您认为窗口命名空间更容易变得混乱,请选择库命名空间。

        在任何一种情况下,您通常只应创建一个“全局”名称。换句话说,如果您要将函数放在库的命名空间中,最好不要将其命名为 $.myFn。将其命名为 $.yaya3.myFn,然后在您多次调用 myFn 的任何上下文中缓存对它的本地引用。

        引用您的函数的最佳实践是将其所在的命名空间作为参数传递给匿名函数:

        (function (yaya3) {   
        var myFn = yaya3.myFn;
        myFn("frobnard!");
        }(window.yaya3)); // you could instead pass $.yaya3 or YUI.namespace("yaya3") here
        

        如果您发现需要移动到不同的命名空间,这会变得容易得多。

        【讨论】:

        • 我真的不明白这能给你带来什么。首先,作为一个库维护者,我不会制作 yaya4,除非它不会向后兼容,在这种情况下,无论如何你都必须审核你的代码;其次,如果您确实想更改为 yaya4,如果您只是将所有对 yaya3 的引用替换为 yaya4,代码会不会更具可读性?
        【解决方案5】:

        我倾向于自己将自定义代码添加到库中。最大的原因是使用语义在内置代码和我的自定义代码中保持一致。话虽如此,我真的想不出这种方法的任何技术优势或劣势。我认为您对冲突的担忧是有效的,尽管可能不太可能(如果您最终得到一个与您的自定义函数之一冲突的组件/模块,很可能是因为您正在用其他人的代码替换您的代码)。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-08-11
          • 2013-05-20
          • 1970-01-01
          • 2011-08-16
          • 1970-01-01
          • 2016-06-21
          • 2014-10-28
          • 1970-01-01
          相关资源
          最近更新 更多