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,前者是變量聲明,帶不可刪除屬性,因此無法被刪除;后者為全局變量的一個屬性,因此可以從全局變量中刪除。
下面看例子:
Javascript聲明變量時
var aaa = 111;
和
aaa = 111;
兩種方式一樣嗎?
廢話少說,先上代碼.
var aaa = 11; function test4(){ var aaa = 22; } test4(); console.log(aaa);
結果是什么呢? 11
這個好理解, 函數內的var aaa聲明是內部變量,這時結果是第一個aaa的值.
變動一下如下:
var abc = 11; function test4(){ abc = 22; } test4(); console.log(abc);
結果是什么呢? 22
再改:
function test4(){ var aaa = 22; } test4(); console.log(aaa);
結果怎樣? 運行報錯了! ReferenceError: aaa is not defined!
改:
function test4(){ var aaa = 22; } test4(); console.log(test4.aaa);
運行不會報錯,輸出結果是 undefined.
結論1: 函數或者對象構造內聲明的變量是私有的. 外部無法訪問到. 包括原型繼承后的對象.
可是如果這樣:
function test4(){ bbb = 33; } test4(); console.log(bbb);
結果是 33
點解?
這就是有var 和沒有 var的聲明的區別.
結論2: 不加var 在函數或者構造內就是賦值, 從函數內往上一層層尋找變量bbb,一直到頂層沒有. 就在頂層聲明一個 var bbb;
很可怕假如一個大的項目,在這里改變了bbb的值, 並沒有添加var 碰巧整個項目全局變量有個同名bbb被改變,不加var不是只作用在這個函數或對象內. 出了錯誤很難找.
所以書寫代碼必須謹慎. 聲明變量改加的就加不能怕麻煩. 結果是完全不同的.