2

我对 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 语句在做什么?它是否在全局范围内创建了一个新的 var,MyVar它被分配了现有的值MyVar

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

谢谢

4

4 回答 4

2

您的代码是正确的,并且可能会按预期工作,但请记住MyVar创建的范围。假设您的文件已发布,它们将MyVarwindow范围内创建(假设浏览器上下文)。如果其中一个被包装在匿名函数中,就像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);
于 2013-01-10T23:42:09.183 回答
2

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

它们中的任何一个是异步加载的吗?如果只是一系列<script>标签,它们将同步加载,按顺序加载。

我将苹果属性分配给哪个 MyVar?

如果MyVar每次都在全局作用域上声明,则只有一个MyVar. 该apple属性将在现有变量上创建(如果存在),或者在创建的空对象中创建(var MyVar = MyVar || {};如果不存在)。

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

于 2013-01-11T00:12:50.170 回答
1

这很容易测试:

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

console.log(MyVar);

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

console.log(MyVar);
于 2013-01-10T23:38:37.140 回答
0

我就是这样做的:

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

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

于 2013-01-11T00:34:09.367 回答