var的反作用
隱式全局變量和明肯定義的全局變量間有些小的差別,就是經過delete操做符讓變量未定義的能力。函數
- 經過var建立的全局變量(任何函數以外的程序中建立)是不能被刪除的。
- 無var建立的隱式全局變量(無視是否在函數中建立)是能被刪除的。
這代表,在技術上,隱式全局變量並非真正的全局變量,但它們是全局對象的屬性。屬性是能夠經過delete操做符刪除的,而變量是不能的:測試
03 |
global_novar = 2; // 反面教材 |
05 |
global_fromfunc = 3; // 反面教材 |
09 |
delete global_var; // false |
10 |
delete global_novar; // true |
11 |
delete global_fromfunc; // true |
14 |
typeof global_var; // "number" |
15 |
typeof global_novar; // "undefined" |
16 |
typeof global_fromfunc; // "undefined" |
在ES5嚴格模式下,未聲明的變量(如在前面的代碼片斷中的兩個反面教材)工做時會拋出一個錯誤。spa
vars變量預解析
JavaScript中,你能夠在函數的任何位置聲明多個var語句,而且它們就好像是在函數頂部聲明同樣發揮做用,這種行爲稱爲 hoisting(懸置/置頂解析/預解析)。當你使用了一個變量,而後不久在函數中又從新聲明的話,就可能產生邏輯錯誤。對於JavaScript,只要你的變量是在同一個做用域中(同一函數),它都被當作是聲明的,即便是它在var聲明前使用的時候。看下面這個例子:code
2 |
myname = "global" ; // 全局變量 |
4 |
alert(myname); // "undefined" |
6 |
alert(myname); // "local" |
在這個例子中,你可能會覺得第一個alert彈出的是」global」,第二個彈出」loacl」。這種期許是能夠理解的,由於在第一個alert 的時候,myname未聲明,此時函數確定很天然而然地看全局變量myname,可是,實際上並非這麼工做的。第一個alert會彈 出」undefined」是由於myname被當作了函數的局部變量(儘管是以後聲明的),全部的變量聲明當被懸置到函數的頂部了。所以,爲了不這種混亂,最好是預先聲明你想使用的所有變量。對象
上面的代碼片斷執行的行爲可能就像下面這樣:baip
1 |
myname = "global" ; // global variable |
3 |
var myname; // 等同於 -> var myname = undefined; |
4 |
alert(myname); // "undefined" |
6 |
alert(myname); // "local"} |
爲了完整,咱們再提一提執行層面的稍微複雜點的東西。代碼處理分兩個階段,第一階段是變量,函數聲明,以及正常格式的參數建立,這是一個解析和進入上下文 的階段。第二個階段是代碼執行,函數表達式和不合格的標識符(爲聲明的變量)被建立。可是,出於實用的目的,咱們就採用了」hoisting」這個概念, 這種ECMAScript標準中並未定義,一般用來描述行爲。作用域