【问题标题】:Javascript global variable redefinition?Javascript全局变量重新定义?
【发布时间】:2013-01-10 23:25:07
【问题描述】:

我对 Javascript 中的变量范围有疑问。我在不同时间加载的网页上有一系列脚本。例如,我需要一个名为 MyVar 的全局对象,以便所有人都可以访问。我想避免重新定义它,但我想它必须在某个时候由第一个脚本定义。我的问题是使用var MyVar = MyVar || {} 解决方案吗?

谢谢

 /**
 * Script 1
 */


var MyVar = MyVar || {};
MyVar.config = {
    x : 2,
    y : 3
};


/**
* Script 2
*/

//is this correct?
var MyVar = MyVar || {};
//to which MyVar am I assigning the apple property?
MyVar.apple = 'red';

更新

到目前为止,伙计们给出了很好的答案。

最后一部分,当我第二次重复var MyVar = MyVar || {}; 时,第二个 var 语句在做什么?它是否在名为 MyVar 的全局范围内创建了一个新变量,该变量被分配了现有 MyVar 的值?

其他发帖人认为我在<script> 标签中同步加载了这些脚本是正确的,但是由于分工,我创建脚本然后不控制它们何时以及如何加载,因此需要一种万无一失的方法来创建/ 利用我的MyVar 对象。

谢谢

【问题讨论】:

标签: javascript variables scope global-variables


【解决方案1】:

我在不同时间加载的网页上有一系列脚本

它们中的任何一个是异步加载的吗?如果只是一串<script>标签,会同步加载,依次加载。

我要将 apple 属性分配给哪个 MyVar?

如果你每次都在全局范围内声明MyVar,那么MyVar就只有一个。 apple 属性将在现有变量上创建(如果存在),或者在使用 var MyVar = MyVar || {}; 创建的空对象中创建(如果不存在)。

底线:在第一个var MyVar = MyVar || {}; 之后,后面的声明将被忽略,新的属性将被附加到现有的变量中。请注意不要覆盖现有属性。

【讨论】:

  • 这是一个很好的解释。最后一部分,当我第二次重复 var MyVar = MyVar || {}; 时,第二个 var 语句在做什么?它是否在名为 MyVar 的全局范围内创建了一个新变量,该变量被分配了现有 MyVar 的值?
  • 它会做MyVar = MyVar(基本上什么都不做)。
  • @JackMahoney - 澄清一下,只有特定变量名的第一个 var 定义实际上定义了该变量。对于相同变量名的任何后续var 语句基本上什么都不做;具体来说,它不会创建具有相同名称的新变量。
【解决方案2】:

您的代码是正确的,并且可能会按预期工作,但请记住 MyVar 的创建范围。假设您的文件已发布,它们将在window 范围内创建MyVar(假设浏览器上下文)。如果其中一个被封装在一个匿名函数中,就像Module Pattern 的常见做法一样,MyVar 只会在该函数的范围内创建:

(function() {
    var MyVar = MyVar || {};
    // If MyVar doesn't already exist in the global context,
    // the current MyVar reference will only be scoped to this function.
})();

更好的使用模式是:

var MyVar = window.MyVar || (window.MyVar = {});

这将确保始终从全局范围创建和引用它。您甚至可以传入上下文以使未来的重构更容易:

(function(context) {
    var MyVar = context.MyVar || (context.MyVar = {}));
})(window);

【讨论】:

  • 谢谢。那么var MyVar = window.MyVar 中的MyVar 是对window.MyVar 的引用还是赋值?
  • 如果window.MyVar 存在,您的本地MyVar 变量将是对它的引用。如果不存在,第二部分|| (window.MyVar = {}) 将创建一个新对象,将其分配给window.MyVar,并返回将分配给本地MyVar 变量的引用。
【解决方案3】:

这很容易测试:

var MyVar = MyVar || {};
MyVar.config = {
    x : 2,
    y : 3
};

console.log(MyVar);

var MyVar = MyVar || {};
MyVar.apple = 'red';

console.log(MyVar);

【讨论】:

  • 如果脚本被引用的顺序改变了怎么办?你的例子不是很好的防御性编程。
  • 我把它看成两个独立的窗口级脚本。我想它们可以在 html 中重新排序,但我认为这超出了 Jack 的问题。
  • @ic3b3rg 你说得对,它们是两个独立的脚本,我不知道它们的顺序是什么
  • 在这种情况下,@roryf 的建议会更好,尽管您可能会发现我的使用 console.log 进行测试的建议很有帮助。
【解决方案4】:

这就是我的做法:

window.myVar||(window.myVar={});

这样,如果变量已经存在,您就不会重新声明它。

【讨论】:

    猜你喜欢
    • 2020-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-22
    • 2021-03-11
    • 1970-01-01
    相关资源
    最近更新 更多