我被告知不应该使用命名空间,因为它们“污染”了全局范围。我想知道有什么替代方案?
当我想定义效用函数和/或常量时,例如对于一个网站,一个简单的方法是通过命名空间来定义它们,这样对全局范围的损害仅限于一个对象。
如果命名空间是不好的做法,我会想到几个问题:
此问题是在a post on the benefits of using extend.js开始讨论的结果。
答案 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)
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...