9

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

对此似乎有两种不同的方法-

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

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

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

4

5 回答 5

16

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

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

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

于 2010-06-30T23:40:08.693 回答
3

我个人喜欢这种方法:

(function(namespace) {

function myPrivateFunction(){};

namespace.myPublicFunction = function(){};

})($); // passing the $ namespace, but if it clutters, 
       // we can change it to something else
于 2010-07-03T12:13:21.187 回答
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);
于 2010-07-03T07:45:15.713 回答
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

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

于 2010-06-30T23:30:07.553 回答
1

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

于 2010-06-13T23:33:00.777 回答