为什么名称空间在JavaScript中被认为是不好的做法?
我被告知不应该使用名称空间,因为它们“污染”了全局范围。我想知道还有什么选择 当我想定义实用程序函数和/或常量(例如,对于网站)时,一个简单的方法是通过名称空间来定义它们,这样对全局范围的损害仅限于一个对象 如果名称空间是一种糟糕的做法,那么我会想到几个问题:为什么名称空间在JavaScript中被认为是不好的做法?,javascript,namespaces,Javascript,Namespaces,我被告知不应该使用名称空间,因为它们“污染”了全局范围。我想知道还有什么选择 当我想定义实用程序函数和/或常量(例如,对于网站)时,一个简单的方法是通过名称空间来定义它们,这样对全局范围的损害仅限于一个对象 如果名称空间是一种糟糕的做法,那么我会想到几个问题: 为什么这是一个坏习惯 此声明的范围是什么(web应用程序/动态网站/静态网站等) 有哪些替代方案 这个问题是从上开始讨论的结果。我个人认为,那些说你永远不应该污染全球范围的人没有正确定义“污染”。例如,您可以在本机Math对象中某种程度上
这个问题是从上开始讨论的结果。我个人认为,那些说你永远不应该污染全球范围的人没有正确定义“污染”。例如,您可以在本机
Math
对象中某种程度上看到这一点。我所知道的每一种编程语言都将所有数学函数作为普通函数,但JS没有。然而,如果你想把它发挥到极致,一个简单的警告框应该是core.dialog.alert
我喜欢将所有代码封装在闭包中,以保持变量干净。但是,我的主JS脚本文件在全局范围内定义了一系列实用函数,例如自定义的Alert()
,或AJAX()
,或其他广泛使用的函数。如果我要经常使用它们,我不想用名称空间调用使文件膨胀。由于我在闭包中定义了所有变量,因此没有意外覆盖函数的风险(我可能在闭包中这样做,但对全局范围没有影响)
总的来说,名称空间被高估了。只需编写代码,不要为每一个
窗口属性哭泣。我无法想象为什么名称空间会是一件坏事。除非有一些特定于JavaScript的名称空间定义是我不知道的
我目前正在开发一个小型库,所有内容都包含在一个顶级对象(名称空间?)中。我不把任何东西放在窗口或内在类型上;如果您需要我的库中的内容,可以在kilo
对象中找到
对我来说,拥有这个“名称空间”是一个很好的实践,因为它可以让我很快知道是否在调用库中的方法。不需要重写窗口。alert
方法,该方法可能会破坏页面上加载的另一个库;只需对自定义版本使用kilo.alert
(这是一个精心设计的示例,但我希望它能说明问题)
为什么这是一个坏习惯
名称空间本身是不好的,因为它是一个不必要的概念
具有具有属性和方法的对象是可以接受的。有一个类似于“名称空间”的“模块”标记也很好,但它的意思是每个文件有一个包含所有属性和方法的“模块”标记。这与“名称空间”不同,因为它只在单个文件中创建/更改,而不是作为全局令牌公开
此声明的范围是什么(web应用程序/动态网站/静态网站等)
所有ECMAScript,从不创建新的全局令牌
有哪些替代方案
与其使用名称空间,不如使用多个“文件本地”标记。这意味着每个文件/“模块”都应该包装在一个闭包中,并且您应该可以访问该闭包中的多个局部变量
全局变量也很糟糕,因为你根本不需要它们。避免全局性的方法是将所有内容包装在闭包中,并在加载外部javascript文件时保持智能
零全局模块装入器示例
进一步阅读:
JavaScript中的“名称空间”实际上只是具有命名属性的对象。在其他OO语言(即C++、C等)中,我认为您不需要以下内容:
#--
只是为了让你能
MyAppName.MyArea.MySubArea.Test.Property1;
因此,基本上,由于JS实际上不支持名称空间,人们发明了一种模拟名称空间的方法,这使得编写以下内容变得“酷”:
myAppSpace.mySubArea.myObject = blah...
我一直认为名称空间正是为了不污染全局范围。。。(->
他们很好)。是的,有人把这个倒过来了。@FelixKling名称空间仍然污染全局范围。您永远不需要JavaScript中的全局标记。任何使用它们的人都犯了错误。@Raynos:当然,每个顶级名称空间都会在全局范围内创建一个符号。。。但是,如果外部库不能访问,您将如何访问它?@FelixKling使用闭包的自定义模块加载程序。库不应该公开全局令牌,它们应该使用标准格式(如AMD或commonJS)公开它们的模块,模块加载器应该提取这些模块并处理模块间的依赖关系。这可以通过零用户创建的全局标记(甚至避免临时全局标记)来实现。如果您建议人们使用全局变量,这是一种不好的做法。在某些环境中,名称空间和其他技术更有用,因为您的分层库可能会发生冲突。例如,JIRA使用名称空间将jQuery之类的东西放在窗口范围之外,但是它使用了大量的库,所以它是有意义的。总的来说,还没有人指出为什么应该避免JS中的全局变量,这是因为它们很容易被任何其他脚本覆盖,如果发生这种情况,您可能会遇到问题。因此,在一般情况下要小心,不要过分夸大。globals的另一个问题是,globals是全局的,任何东西都可以读取/修改/损坏/更改/通常会弄乱它们。这与不应将SQL查询直接嵌入服务器端web应用程序的视图的概念类似。基本上是全局中断
myAppSpace.mySubArea.myObject = blah...