全域性作用域下變數加var和不加var的區別
頁面導航
第二個區別:加var的變數即是window的屬性又是全域性變數
第一個區別
如果變數名在全域性作用域下不加var,則瀏覽器不會對這個變數進行預解析。
如果沒有給變數名加var,也沒有給這個變數賦值,那麼在console.log()輸出時會報錯。而給變數名加了var的變數,即使不賦值,console.log()是能輸出的,只是輸出結果是undefined而已。
看如下程式碼和結果:
(不加var的變數名a,輸出會直接報錯,報錯後不執行後面的操作)
瀏覽器輸出的結果是:
所以,如果在全域性作用域下不給變數名加var,同時也不賦值,就進行console.log的操作就會報錯。
在JavaScript中,上一行程式碼報錯了,則下一行程式碼是不會執行的,所以後續並沒有執行console.log(b)的操作。
那麼我們現在把上面的程式碼換一個順序,如下圖:
(變數名加了var後,即使不賦值,也是可以輸出的,只是輸出結果是undefined)
在瀏覽器中顯示的結果為:
第二個區別
如果變數名不加var: 但是給變數賦值了,那麼就是給window增加了一個屬性名和屬性值。例如:
a=12;其實是window.a=12;
不加var的變數,如果賦值了就是給window新增了一個屬性。
如果變數名加了var: 不僅僅是給window加了一個屬性名和值,同時也定義了一個全域性變數。
所以說加var的變數會有兩種效果,一種是window的屬性,一種是全域性變數。
根據瀏覽器的執行順序:
如果瀏覽器遇到變數,會先從全域性變數下查詢是否存在。如果不存在,再到window的屬性名裡查詢。如果都不存在,則會報錯。
例如:console.log(a); a既不是全域性也不是window屬性所以輸出時會報錯。
如下程式碼,說明不加var變數名賦值後是window的屬性
( c變數名沒有加var,但是賦值了,所以c是window的屬性,瀏覽器解析不是全域性變數後,會到window的屬性名下查詢,如果能找到就會輸出):
輸出結果為:
所以,沒有加var的變數,賦值後這個變數就是window的屬性了。
第三個區別
不加var的屬性賦值後就是window下的屬性。如果是window下的屬性,那麼用delete關鍵字就可以刪除這個屬性。如果是全域性變數下的屬性,那麼使用window的關鍵字是無法刪除的。
例如:
(delete 把c刪除後,window下就沒有這個屬性了,那麼你要輸出它就會報錯)
瀏覽器輸出的結果是:
如果屬性加了var,那麼這個屬性即是window下的,同時又是全域性屬性。而delete關鍵字只能刪除window下的屬性,不能刪除全域性作用域下的屬性。
如下圖:
(c變數加了var後,即是用delete刪除也是刪除在window下的屬性,則全域性下是不會被刪除的)
瀏覽器輸出的結果是:
所以,加了var的變數delete是無法刪除的。
為了避免是屬性的作用域出現混淆,所以建議以後只要是變數就都加一個var。