2013-01-10 213 views
1

我有一個關於Javascript中的變量範圍的問題。我在不同的時間在網頁上加載了一系列腳本。我需要一個名爲MyVar的全局對象,以便他們都可以訪問它們。我想避免重新定義它,但我想它必須在第一個腳本的某個時刻定義。我的問題是使用var MyVar = MyVar || {}的解決方案?Javascript全局變量重定義?

感謝

/** 
* 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'; 

UPDATE

偉大的答案至今傢伙感謝。

雖然最後一部分,第二次var語句在第二次重複var MyVar = MyVar || {};時是幹什麼的?它是否在全球範圍內創建了一個名爲MyVar的新變量,該變量分配了現有的MyVar的值?

其他海報是正確的假設我有這些腳本同步加載在<script>標籤,但由於分工我創建腳本,然後不控制何時以及如何加載,所以需要一個傻瓜式的方法來創建/利用我的MyVar對象。

感謝

+1

查看[有關處理全局變量時的最佳做法的此問題](http://stackoverflow.com/q/5063878/562906) – sinelaw

+1

是的,您的代碼將起作用。是的,你應該儘可能避免使用全局變量。 – wless1

+0

閱讀'var MyVar = MyVar || {};'如果var MyVar = MyVar存在(並且不等於false或0),則爲'var MyVar = MyVar;如果不存在則爲新對象。 – ic3b3rg

回答

2

我有一個網頁在不同的時間

是其中的任何異步加載加載一系列的腳本?如果它只是一系列<script>標籤,則它們將按順序同步加載。

MyVar分配的蘋果屬性?

如果在全球範圍內每一次申報MyVar,將只有一個MyVarapple屬性將在現有變量(如果存在)上創建,或者在var MyVar = MyVar || {};創建的空對象(如果不存在)上創建。

底線:在第一個var MyVar = MyVar || {};之後,下面的聲明將被忽略,並且新的屬性會被追加到現有的變量中。請注意不要覆蓋現有的屬性。

+0

這是一個很好的解釋。最後一部分,當我重複'var MyVar = MyVar ||時,第二個var語句是做什麼的{};'第二次?它是否在全局範圍內創建了一個名爲'MyVar'的新變量,該變量被分配了現有的'MyVar'的值? – JackMahoney

+0

它會做'MyVar = MyVar'(基本上什麼都不做)。 – bfavaretto

+1

@JackMahoney - 爲了澄清,只有特定變量名稱的第一個'var'定義實際上定義了該變量。任何後續的'var'語句對於同一個變量名基本上什麼都不做;具體而言,它不會*創建一個具有相同名稱的新變量。 –

1

這很容易測試:

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

console.log(MyVar); 

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

console.log(MyVar); 
+0

如果腳本被引用的順序改變了怎麼辦?你的榜樣不是很好的防守編程。 – roryf

+0

我把它作爲兩個獨立的窗口級腳本來讀取。我想他們可以在html中重新排序,但我認爲這超出了Jack的問題。 – ic3b3rg

+0

@ ic3b3rg你是對的,他們是兩個單獨的腳本,我不知道他們將在 – JackMahoney

2

你的代碼是正確的,並預期可能會工作,但切記在其中創建MyVar範圍。假設您的文件已發佈,它們將在window範圍內(假設瀏覽器上下文)創建MyVar。如果其中一個被包裹在一個匿名函數,這是常見的做法與Module PatternMyVar只會在該函數的範圍內創建:

(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); 
+0

謝謝。所以'var MyVar = window.MyVar'是'MyVar'對'window.MyVar'的引用還是賦值? – JackMahoney

+0

如果存在'window.MyVar',那麼你的本地'MyVar'變量將是對它的引用。如果它不存在,第二部分'|| (window.MyVar = {})將創建一個新對象,將其分配給'window.MyVar'並返回將被分配給本地'MyVar'變量的引用。 – roryf

0

這是我要做的事:

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

這樣,你是不是重新聲明變量,如果它已經存在。