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

9
在JavaScript中,全局作用域中声明变量是不好的事情,这一点相当有名。因此,我通常处理的代码包含命名空间JavaScript。
似乎有两种不同的方法:
1.将应用程序特定的函数添加到库的命名空间中,例如:$.myCarouselfunction。 2.创建自己的命名空间,例如:MyApplication.myCarouselFunction。
我想知道是否有更好的解决方案,或者它们在利弊方面是否趋于接近。
对于我个人决定不使用库的原因是为了分离/隔离/避免与库代码和可能共享该命名空间的插件产生冲突。是否还有其他需要考虑的因素?
5个回答

16

我认为在选择这种东西时最重要的是语义

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

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


我同意,但请记住,使用命名空间可以避免潜在的名称冲突,特别是在库更新后,尤其是在JavaScript中,您可以重新定义一个变量,而一切都像什么都没有发生一样。 - user347594

3

个人而言,我喜欢这种方法:

(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);

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

如果你发现需要移动到另一个命名空间,这将使得操作变得更加容易。


我真的不明白这给你带来了什么好处。首先,作为一个库维护者,除非它不向后兼容,否则我不会制作yaya4,这种情况下,您必须审核您的代码;其次,如果您确实想要更改为yaya4,如果您只是用yaya4替换所有对yaya3的引用,那么代码不是更易读了吗? - nas

1

我倾向于自己将自定义代码添加到库中。最大的原因是为了使内置代码和我的自定义代码的使用语义保持一致。话虽如此,我真的想不出这种方法有什么技术上的优劣势。我认为你对冲突的担忧是合理的,但可能不太可能发生(如果你最终得到一个与你的自定义函数冲突的组件/模块,很可能是因为你正在用别人的代码替换你的代码)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接