为什么命名空间在JavaScript中被认为是不好的做法?

时间:2012-04-07 11:39:15

标签: javascript namespaces

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

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

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

  1. 为什么这是不好的做法?
  2. 此声明的范围是什么(网络应用程序/动态网站/静态网站等)?
  3. 有哪些替代方案?
  4. 此问题是在a post on the benefits of using extend.js开始讨论的结果。

4 个答案:

答案 0 :(得分:8)

  

为什么这是不好的做法?

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

具有属性和方法的对象是可以接受的。拥有一个类似于“命名空间”的“模块”标记也没关系,但意思是每个文件都有一个“模块”标记,其中包含所有属性和方法。这与“名称空间”不同,因为它仅在单个文件中创建/更改,不会作为全局标记公开。

  

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

所有ECMAScript,永远不会创建新的全局令牌

  

有哪些替代方案?

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

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

零全局模块加载器的示例

进一步阅读:

答案 1 :(得分:3)

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

我目前正在开发一个小型库,一切都被一个顶级对象(名称空间?)包围。我不把任何东西放在窗户或内在类型上;如果您需要我的库中的某些内容,可以在kilo对象中找到它。

对我来说,拥有这个'命名空间'是一种良好的练习,因为如果我在我的库中调用一个方法,它会让我很快知道。没有必要覆盖可能与页面上加载的另一个库混在一起的window.alert方法;只需使用kilo.alert作为自定义版本(这是一个人为的例子,但我希望它能说明问题。)

答案 2 :(得分:2)

就我个人而言,我认为那些说你从不污染全球范围的人未能正确定义“污染”。例如,您可以在本地Math对象中看到这种情况。我所知道的所有其他编程语言都具有所有数学函数,只是普通函数,但JS没有。但是,如果您将此视为极端,例如,简单的警告框将为core.dialog.alert

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

总体而言,名称空间被高估了。只需编写代码,不要为每个window属性而哭泣。

答案 3 :(得分:1)

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实际上并不支持命名空间,所以人们发明了一个模拟命名空间的黑客攻击,这使得编写类似的东西变得很酷:

myAppSpace.mySubArea.myObject = blah...