讀古今文學網 > 編寫高質量代碼:改善JavaScript程序的188個建議 > 建議3:減少全局變量污染 >

建議3:減少全局變量污染

定義全局變量有3種方式:

❑在任何函數外面直接執行var語句。


var f='value';


❑直接添加一個屬性到全局對像上。全局對象是所有全局變量的容器。在Web瀏覽器中,全局對像名為window。


window.f='value';


❑直接使用未經聲明的變量,以這種方式定義的全局變量被稱為隱式的全局變量。


f='value';


為方便初學者在使用前無須聲明變量而有意設計了隱式的全局變量,然而不幸的是忘記聲明變量成了一個非常普遍的現象。JavaScript的策略是讓那些被忘記預先聲明的變量成為全局變量,這導致在程序中查找Bug變得非常困難。

JavaScript語言最為糟糕的就是它對全局變量的依賴性。全局變量就是在所有作用域中都可見的變量。全局變量在很小的程序中可能會帶來方便,但隨著程序越來越大,它很快變得難以處理。因為一個全局變量可以被程序的任何部分在任意時間改變,使得程序的行為被極大地複雜化。在程序中使用全局變量降低了程序的可靠性。

全局變量使在同一個程序中運行獨立的子程序變得更難。如果某些全局變量的名稱與子程序中的變量名稱相同,那麼它們將會相互衝突並可能導致程序無法運行,而且通常還使程序難以調試。

實際上,這些全局變量削弱了程序的靈活性,應該避免使用全局變量。努力減少使用全局變量的方法:在應用程序中創建唯一一個全局變量,並定義該變量為當前應用的容器。


var My={};

My.name={

"first-name":"first",

"last-name":"last"

};

My.work={

number:123,

one:{

name:"one",

time:"2012-9-14 12:55",

city:"beijing"

},

two:{

name:"two",

time:"2012-9-12 12:42",

city:"shanghai"

}

};


只要把多個全局變量都追加在一個名稱空間下,將顯著降低與其他應用程序產生衝突的概率,應用程序也會變得更容易閱讀,因為My.work指向的是頂層結構。當然也可以使用閉包體將信息隱藏,它是另一種有效減少「全局污染」的方法。

在編程語言中,作用域控制著變量與參數的可見性及生命週期。這為程序開發提供了一個重要的幫助,因為它減少了名稱衝突,並且提供了自動內存管理。


var foo=function{

var a=1,b=2;

var bar=function{

var b=3,c=4;//a=1,b=3,c=4

a+=b+c;//a=8,b=3,c=4

};//a=1,b=2,c=undefined

bar;//a=21,b=2,c=undefined

};


大多數採用C語言語法的語言都擁有塊級作用域。對於一個代碼塊,即包括在一對大括號中的語句,其中定義的所有變量在代碼塊的外部是不可見的。定義在代碼塊中的變量在代碼塊執行結束後會被釋放掉。但是,對於JavaScript語言來說,雖然該語言支持代碼塊的語法形式,但是它並不支持塊級作用域。

JavaScript支持函數作用域,定義在函數中的參數和變量在函數外部是不可見的,並且在一個函數中的任何位置定義的變量在該函數中的任何地方都可見。

其他主流編程語言都推薦盡可能遲地聲明變量,但是在JavaScript中就不能夠這樣,因為它缺少塊級作用域,最好的做法是在函數體的頂部聲明函數中可能用到的所有變量。