4

我被告知不应使用命名空间,因为它们会“污染”全局范围。我想知道有什么替代方案?

当我想为网站定义实用程序函数和/或常量时,一种简单的方法是通过命名空间定义它们,这样对全局范围的损害仅限于一个对象。

如果命名空间是不好的做法,那么会想到几个问题:

  1. 为什么这是不好的做法?
  2. 该声明的范围是什么(网络应用程序/动态网站/静态网站等)?
  3. 有哪些替代方案?

这个问题是在一篇关于使用 extend.js 的好处的帖子上开始讨论的结果。

4

4 回答 4

8

为什么这是不好的做法?

命名空间本身很糟糕,因为它是一个不必要的概念。

拥有具有属性和方法的对象是可以接受的。拥有一个类似于“命名空间”的“模块”令牌也很好,但其含义是每个文件都有一个“模块”令牌,其中包含所有属性和方法。这与“命名空间”不同,因为它仅在单个文件中创建/更改,并且不作为全局令牌公开。

该声明的范围是什么(网络应用程序/动态网站/静态网站等)?

所有 ECMAScript,从不创建新的全局令牌

有哪些选择?

而不是拥有命名空间,您应该支持多个“文件本地”令牌。这意味着每个文件/“模块”都应该包装在一个闭包中,并且您应该可以访问这个闭包内的多个局部变量。

全局变量也很糟糕,因为你根本不需要它们。避免全局变量的方法是将所有内容包装在闭包中,并在加载外部 javascript 文件的方式上保持智能。

零全局模块加载器示例

进一步阅读:

于 2012-04-07T11:56:15.690 回答
3

我无法想象为什么命名空间会是一件坏事。除非有一些我不知道的特定于 JavaScript 的命名空间定义。

我目前正在开发一个小型库,所有内容都包含在一个顶级对象(命名空间?)中。我没有在窗口或内在类型上放任何东西;如果您需要我的图书馆中的某些东西,它可以在kilo对象中找到。

对我来说,拥有这个“命名空间”是一种很好的做法,因为它可以让我很快知道我是否正在调用库中的方法。无需重写window.alert可能与页面上加载的另一个库发生冲突的方法;仅kilo.alert用于自定义版本(这是一个人为的示例,但我希望它能够说明问题)。

于 2012-04-07T11:52:37.860 回答
2

我个人认为那些说你不应该污染全球范围的人没有正确定义“污染”。例如,您可以在某种程度上在本机Math对象中看到这一点。我知道的所有其他编程语言都将所有数学函数都作为普通函数,但 JS 没有。但是,如果您将其发挥到极致,core.dialog.alert例如,可以使用一个简单的警报框。

我喜欢将我所有的代码封闭在闭包中,以保持变量干净。但是,我的主 JS 脚本文件在全局范围内定义了一堆实用函数,例如自定义Alert()、或AJAX()或其他广泛使用的函数。如果我要经常使用它们,我不想用命名空间调用来膨胀文件。而且由于我在闭包中定义了所有变量,因此不会有意外覆盖函数的风险(我可能会在闭包本身中这样做,但它对全局范围没有影响)。

总的来说,命名空间被高估了。只需编写您的代码,不要为每个window属性哭泣。

于 2012-04-07T11:44:41.253 回答
0

JavaScript 中的“命名空间”实际上只是具有命名属性的对象。在其他 OO 语言(即 C++、C# 等)中,我认为您不需要以下内容:

C# -

public static class MyAppName {}
public static class MyArea {}
public static class MySubArea {}

public static class Test {
  public string Property1 { get { return "test"; }}
}

只是这样你就可以拥有

MyAppName.MyArea.MySubArea.Test.Property1;

所以基本上,因为 JS 实际上并不支持命名空间,所以人们发明了一种 hack 来模拟命名空间,这使得编写如下内容变得“酷”:

myAppSpace.mySubArea.myObject = blah...
于 2012-04-07T11:58:36.850 回答