“隐含的全局变量”有哪些问题?

时间:2011-02-05 20:52:56

标签: javascript namespaces global-variables

JavaScript:好的部分将这些类型的声明定义为错误:

foo = value;

这本书说“JavaScript将全球遗忘变量创造出来的政策 可能很难找到的错误。“

除了典型全局变量的常见危险之外,这些隐含的全局变量有哪些问题?

5 个答案:

答案 0 :(得分:14)

正如this answer的评论所述,设定某些值会产生意想不到的后果。

在Javascript中,这更有可能是因为设置全局变量实际上意味着设置window对象的属性。例如:

function foo (input) {
    top = 45;
    return top * input;
}
foo(5);

这会返回NaN,因为您无法设置window.top并且乘以window对象不起作用。将其更改为var top = 45有效。

您无法更改的其他值包括document。此外,还有其他全局变量,一旦设置,就会做令人兴奋的事情。例如,设置window.status会更新浏览器的状态栏值,window.location会转到新位置。

最后,如果更新某些值,可能会丢失某些功能。例如,如果您将window.frames设置为字符串,则无法使用window.frames[0]来访问框架。

答案 1 :(得分:4)

全局变量使得很难隔离代码,并在新的上下文中重用它。

第1点: 如果你有一个依赖于全局变量的Javascript对象。您将无法在应用程序中创建此对象的多个实例,因为每个实例都将更改全局的值,从而覆盖先前由另一个实例写入的数据。 (当然,除非此变量包含所有实例共有的值 - 但通常情况下,您会发现这样的假设是错误的。)

第2点: Globals使得很难获取现有的代码并在新的应用程序中重用它们。假设您在一个文件中定义了一组函数,并且您希望在其他文件中使用它们(在另一个应用程序中)。因此,您将它们提取到一个新文件,并将该文件包含在新应用程序中。如果这些函数依赖于全局,那么您的第二个应用程序将在运行时失败,因为全局变量不存在。在代码中看不到对全局变量的依赖,因此忘记这些变量(将函数移动到新文件时)可能存在危险。

答案 2 :(得分:1)

它们是全局变量,所以是的,所有“通常的危险”都适用。将它们与其他语言中的全局变量区分开来的主要原因是:

  • 您没有在全局范围内明确声明它们。如果您在变量声明中错误地省略var,则您不小心声明了一个全局变量。 JavaScript使得无意中声明全局变量变得有点容易;将此与Scheme相比较,如果未在全局范围中定义变量,则会引发错误。
  • 全局变量(至少在浏览器中)由window[variable_name]别名。这可能令人担忧。例如,您的一些代码可能会访问window['foo'](旨在访问全局变量)。然后,如果您不小心在程序的其他位置键入foo而不是var foo,则表示您已声明对window['foo']的引用,您打算将其分开。

答案 3 :(得分:0)

一个问题是你可能正在践踏已经定义的变量并且不知道它,导致代码的其他部分产生奇怪的副作用,这些副作用可能会成为追踪的障碍。

另一个是它只是草率的代码。你不应该创建范围超出他们需要的变量,因为它至少会在内存中保留更多的变量,最坏的情况是它可以创建你不想要的数据场景。

最重要的是,当你这样做时,你不确定你是否搞砸了使用同名全局变量的其他函数。有时它甚至不是你的错,另一个插件的懒惰程序员留下了一些全局的东西,意味着在函数内部有范围。因此,编写更好,更少错误的代码是一种非常实用的保障。

答案 4 :(得分:0)

典型的全局变量的问题在于它们是全局的 - 没有可以包含它们的范围,并且您正在执行/与之交互的任何代码(例如您在路上调用的库)都可以修改没有警告的变量。

然而,这些问题在Javascript中由两件事情加剧:

  1. 您可以在任何地方定义全局变量 - 唯一的要求是忘记var关键字。
  2. 当您无意这样做时,定义全局变量非常容易。这就是“暗示”全局变量超过“典型”全局变量的问题 - 你甚至不知道自己就会创建它们。
  3. 在一个设计合理的语言中,包含真正的全局变量(好的,所以 合理设计),你将有一些限定的全局变量的地方,它需要一个特殊的这样做的关键字。