Javascript JS中的全局变量有害吗?

Javascript JS中的全局变量有害吗?,javascript,Javascript,本文认为, JS中的全局变量非常危险 很抱歉是德语,但我要指出这篇文章的两个主要观点 第一个已经在head声明的第2段中 它说“在JS中,全局变量是危险的,因为它们可以通过名称被其他脚本访问”,到目前为止这很好,因为这就是我想使用全局变量的主要方式,不是吗 但在这篇文章中,这似乎是随机发生的。这肯定不是预期的行为,是吗 但更让我害怕的是最后一句话。它预测,如果函数声明 全局变量被多次调用。 但是,如果名称仍然相同,这怎么可能发生呢?如何使用相同的名称声明多个全局变量? 或者这篇文章可能是由某个

本文认为,

JS中的全局变量非常危险

很抱歉是德语,但我要指出这篇文章的两个主要观点

第一个已经在head声明的第2段中

它说“在JS中,全局变量是危险的,因为它们可以通过名称被其他脚本访问”,到目前为止这很好,因为这就是我想使用全局变量的主要方式,不是吗

但在这篇文章中,这似乎是随机发生的。这肯定不是预期的行为,是吗

但更让我害怕的是最后一句话。它预测,如果函数声明 全局变量被多次调用。 但是,如果名称仍然相同,这怎么可能发生呢?如何使用相同的名称声明多个全局变量? 或者这篇文章可能是由某个人写的,只是“知识的一半”?或者只是写给一个根本不习惯全球和本地差异的人? 或者JS真的是这样做的

下面是一个具体的例子:

我希望有人谁登录到我的网页,以创建一个随机生成的令牌,并提交它通过点击登录。 在每个按钮上,我希望这个令牌由不同的函数访问,并提交它,以便只为新登录重新生成密钥

对于这个键,我考虑使用一个全局变量,它由一个函数声明,由另一个函数返回。 但是,由于我将生成/重新生成密钥(可能不止一次),这会导致内存泄漏吗?或者我指的这篇文章可能只是戏剧化的?
如果这确实是JS的行为方式,那么在我的例子中,如何使变量可以从不同的函数访问呢?

关于内存泄漏:假设您有一个函数,您在其中定义了一个
var
,并将其用于某种目的,然后从该函数返回。在这种情况下,变量使用的内存将被释放。但是,如果您依赖一个全局变量来做同样的事情,那么内存将在函数退出后很长时间内继续分配。扩展相同的场景,假设您的函数向该变量添加属性,这些属性的名称取决于函数正在处理的数据(如订单ID、客户名称等)。现在,每次调用您的函数时,越来越多的属性将附加到此变量,并且该变量将不断增长

关于内存泄漏:假设您有一个函数,在其中定义了一个
var
,并将其用于某种目的,然后从函数返回。在这种情况下,变量使用的内存将被释放。但是,如果您依赖一个全局变量来做同样的事情,那么内存将在函数退出后很长时间内继续分配。扩展相同的场景,假设您的函数向该变量添加属性,这些属性的名称取决于函数正在处理的数据(如订单ID、客户名称等)。现在,每次调用您的函数时,越来越多的属性将附加到此变量,并且该变量将不断增长

globals的问题不在于内存,也不在于性能

globals的问题完全不同。问题在于它们引入了全局状态,并且脚本没有绑定到命名空间

让我们一个接一个地讨论这些问题

具有全球状态 这是这里最大的问题。编码要求模块的依赖关系是明确的,并且代码段之间的通信非常清晰

当您有全局变量时,代码的哪一部分使用该变量就不那么清楚了,您无法确定代码的哪一部分需要它,哪一部分不需要

比如说,我有一个
动物园
项目,我有一个
沐浴
服务来清洁动物。我没有将
Bathe
传递给每个需要它的动物,而是将它放在一个全局名称空间中,我只调用
Bathe(myAnimal)

现在我想重组我的动物园,我想知道哪些动物需要洗澡,因为我想优化它。除了通读我的全部代码,我没有办法知道这一点。为了查看我的长颈鹿是否需要洗澡,我必须阅读长颈鹿类的全部代码。相反,如果我将
Bathe
传递给长颈鹿的构造函数,而不是在长颈鹿内部使用或创建它(一个称为依赖注入的概念),我可以通过读取签名看出长颈鹿需要洗澡

现在情况可能变得更糟,如果我有状态呢?如果我真的在多个地方改变一个全局变量,那就很难跟踪了。在超过几行的代码库中,这意味着您的状态到处都在改变,并且没有明确的指示是谁在改变它

这是你应该完全避免使用globals的主要原因

脚本未绑定到命名空间 如果我在一个页面上有两个脚本,并且我的第一个脚本在全局命名空间上声明了一个
a
变量,那么第二个脚本可以访问该变量。这是很有用的,因为脚本可以以这种方式交互,但这是非常有害的,因为这意味着脚本可以覆盖彼此的代码,并以一种不明确的方式进行通信

当然,如果您使用像browserify这样的模块加载器,或者这意味着您的整个脚本只公开两个全局变量-
require
define
,然后通过加载器完成脚本加载,那么这一问题就会得到完全缓解

这样,独立代码片段的交互方式就得到了很好的定义。这并不妨碍您在全局对象上创建变量,但有助于减少以统一方式创建变量的需要

关于安全的说明 当然,什么都行