我对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
的全局范围内创建了一个新的var,并为其分配了现有MyVar
的值?
其他海报是正确的假设我在<script>
标签中同步加载这些脚本但是由于分工我创建脚本然后不控制它们何时以及如何加载所以需要一个万无一失的方法创建/使用我的MyVar
对象。
由于
答案 0 :(得分:2)
您的代码是正确的,可能会按预期工作,但请记住MyVar
的创建范围。假设您的文件已发布,他们将在MyVar
范围内创建window
(假设浏览器上下文)。如果其中一个被包装在一个匿名函数中,这是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);
答案 1 :(得分:2)
我在不同时间加载的网页上有一系列脚本
是否有任何异步加载?如果它只是一系列<script>
标签,它们将按顺序同步加载。
MyVar我指定苹果属性?
如果您每次都在全局范围内声明MyVar
,则只会有一个MyVar
。 {“1}}属性将在现有变量上创建(如果存在),或者在使用apple
创建的空对象中创建(如果不存在)。
底线:在第一个var MyVar = MyVar || {};
之后,将忽略以下声明,并且新属性将附加到现有变量。请注意不要覆盖现有属性。
答案 2 :(得分:1)
这很容易测试:
var MyVar = MyVar || {};
MyVar.config = {
x : 2,
y : 3
};
console.log(MyVar);
var MyVar = MyVar || {};
MyVar.apple = 'red';
console.log(MyVar);
答案 3 :(得分:0)
我就是这样做的:
window.myVar||(window.myVar={});
这样,如果变量已经存在,则不会重新声明该变量。