共享JavaScript库的命名空间还是使用自己的命名空间?

时间:2010-06-13 23:13:53

标签: namespaces javascript global-scope

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

似乎有两种不同的方法 -

  1. 将特定于应用程序的函数添加到库的命名空间,例如$.myCarouselfunction
  2. 创建自己的命名空间,例如MyApplication.myCarouselFunction
  3. 我想知道是否有更好的解决方案,或者他们是否倾向于在优点和缺点方面达到接近的地方。

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

5 个答案:

答案 0 :(得分:16)

我认为选择此类事情最重要的是语义

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

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

答案 1 :(得分:3)

我个人喜欢这种方法:

(function(namespace) {

function myPrivateFunction(){};

namespace.myPublicFunction = function(){};

})($); // passing the $ namespace, but if it clutters, 
       // we can change it to something else

答案 2 :(得分: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 :(得分:1)

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

答案 4 :(得分:1)

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

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

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

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

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