Javascript聲明變數的時候,雖然用var關鍵字聲明和不用關鍵字聲明,很多時候運行並沒有問題,但是這兩種方式還是有區別的。可以正常啟動並執行代碼並不代表是合適的代碼。
var num = 1;
是在當前域中聲明變數. 如果在方法中聲明,則為局部變數(local variable);如果是在全域域中聲明,則為全域變數。
而 num = 1;
事實上是對屬性賦值操作。首先,它會嘗試在當前範圍鏈(如在方法中聲明,則當前範圍鏈代表全域範圍和方法局部範圍etc。。。)中解析 num; 如果在任何當前範圍鏈中找到num,則會執行對num屬性賦值; 如果沒有找到num,它才會在全域對象(即當前範圍鏈的最頂層對象,如window對象)中創造num屬性並賦值。
注意!它並不是聲明了一個全域變數,而是建立了一個全域對象的屬性。
即便如此,可能你還是很難明白“變數聲明”跟“建立對象屬性”在這裡的區別。事實上,Javascript的變數聲明、建立屬性以及每個Javascript中的每個屬性都有一定的標誌說明它們的屬性----如唯讀(ReadOnly)不可枚舉(DontEnum)不可刪除(DontDelete)等等。
由於變數聲明內建不可刪除屬性,比較var num = 1 跟 num = 1,前者是變數聲明,帶不可刪除屬性,因此無法被刪除;後者為全域變數的一個屬性,因此可以從全域變數中刪除。
具體見以下代碼:
複製代碼 代碼如下:// num1為全域變數,num2為window的一個屬性
var num1 = 1;
num2 = 2;
// delete num1; 無法刪除
// delete num2; 刪除
function model(){
var num1 = 1; // 本地變數
num2 = 2; // window的屬性
// 匿名函數
(function(){
var num = 1; // 本地變數
num1 = 2; // 繼承範圍(閉包)
num3 = 3; // window的屬性
}())
}
PS. 在ECMAScript5標準中,有一種“strict 模式”(Strict Mode)。在strict 模式中,為未聲明的標識符賦值將會拋引用錯誤,因此可以防止意外的全域變數屬性的創造。目前一些瀏覽器的新版本已經支援。