JavaScript:window.spam是一个好的实践吗?

3
我注意到很多人在回答类似“如何在函数内部创建全局变量”的问题时都会提到“只需在JS代码的顶部定义一个变量,它就会成为全局变量”。大多数答案都会先说无法实现这一点。当然,实现这一点是可能的:
<script type="text/javascript">
    window.spam = 'Hello World';
</script>

然后,在您的代码中稍后,您可以这样说:
<script type="text/javascript">
    alert(spam);
</script>

这在IE6+、Firefox、Chrome、Safari等浏览器上都可以完美地工作。那么为什么没有人这样做呢?

在我的情况下,我希望人们可以从他们的代码中的任何位置访问名为fooBar的全局变量,在我的AJAX库中,我希望变量能够自动在后台更新,这样当他们使用$.do_some_magic()时,他们可以确信fooBar将反映$.do_some_magic()所做的更改,而不必考虑它。我不希望他们在他们的代码中创建变量,我也不想在我的库代码中创建变量。我想我只是讨厌在顶部定义全局变量,除非有充分的理由不这样做。难道有吗?

2个回答

7

清晰性

这是一种明确的方式,表明您打算创建一个全局变量。

// Unclear: Intentional, or accident
function privateScope() {
  spam = "hello";

  function globalFunction() {

  }
}

这将使一个变量成为全局变量,仅仅因为它被声明为这样,尽管程序员打算让变量和函数具有全局作用域并不是显而易见的。

// Clear: Intentional global use
function privateScope() {
  window.spam = "hello";

  window.globalFunction = function () {

  }
}

这个例子更加明显。

最佳实践

如果您事先知道一个变量将与全局作用域一起使用,它应该在文件顶部声明,在所有函数之外:

var spam;

如果您在一个自执行的匿名函数内部,则需要明确使用 window.spam

(function(){
    // currently private to this scope
    var spam;

    ... lots of code ...

    // Expose the variable publically
    window.spam = spam;
})();

名称冲突

anthares 提出了 另一方面的问题,即名称冲突

许多库会公开一个单一的顶层对象。您可以构建一个函数来实现此目的,也可以使用简单的对象字面量作为命名空间:

(function(){
   // Expose a single top level variable
   window.YourCompany = { };

   // Private:
   var spam = "name";

   ... other code ...


   // Make public
   window.YourCompany.spam = spam;

})();

3
当然,你可以说window.spam。但仅当你还定义了一个名为spam的局部变量时才需要这样做。否则,只需说spam就会自动引用全局变量。
引用未声明var的全局变量是不好的实践,但除非你使用ECMAScript第五版的“严格模式”,否则将起作用。
因为var声明被“提升”并在代码之前处理,所以没有理由必须在“顶部”定义全局变量。这在严格模式下也是完全有效的:
function setFooTo6() {
    fooBar= 6;
}

var fooBar;

虽然我会犹豫这样做,因为并不是完全清楚。


@bobince 我也不知道,虽然我同意这可能不太清楚。 - Doug Neiner

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接