JS中全域性變數和區域性變數
全域性變數,作用域為所屬的整個程式。
定義形式:
- 在函式外定義。
- 在函式內定義,但是不加 var 宣告。
- 使用 window.變數名 的形式定義。(注:相容性未知)
- 使用 window['變數名'] 的形式定義。(注:相容性未知)
區域性變數,作用域為所屬的函式內部。
定義形式:
- 在函式內部定義的變數。
- 函式中用到的形式引數。
例子:
var a =0; //
b =0; //全域性變數
function c() {
var d =0; //
e =0; //全域性變數
return d;
}
console.log(a); //0
console.log(b); //0
console.log(c()); //0
console.log(e); //0
console.log(d); //出錯
幾種情況:
- 區域性變數的變數提升問題以及全域性變數和區域性變數重名的問題。
程式碼:
var a = 0;
b = 0;
function c() {
console.log(a);
var a = 1;
console.log(a);
return a;
}
console.log(a); //0
c(); //undefined,1
理解:
第一條列印結果為 0 ,其中的 變數a 指的是全域性變數a;第二條列印結果為 undefined和1,因為在執行函式c 的時候,並非是從上到下依次執行的各條語句,而是先將定義變數的語句提前執行,其它語句的執行順序不變。即函式c 中實際執行效果程式碼如下:
function c() {
var a;
console.log(a);
a = 1;
console.log(a);
return a;
}
當在函式c中定義了一個與全域性變數一樣的區域性變數a時,函式c內部就會重新定義一個區域性變數a,並將之前定義的全域性變數a覆蓋,不過,這個區域性變數a只是在函式c中有效。由此可知,在函式c中,當第一次列印a時,實際上只定義了局部變數a,而未賦值,所以列印結果為undefined,執行第二條列印區域性變數a時已經對其進行了賦值,所以結果為1。
- 全域性變數和某個函式中的區域性變數重名,如何在該函式中獲得同名全域性變數的值。
程式碼:
var a = 0;
function c() {
console.log(window.a);
var a = 1;
console.log(a);
return a;
}
c(); //0,1
理解:
在函式內部使用 window.變數名 或者 window['變數名'] 即可。
各自優缺點:
- 全域性變數
優點:
- 可以減少變數的個數,減少由於實際引數和形式引數的資料傳遞帶來的時間消耗。
缺點:
- 全域性變數儲存在靜態儲存區,程式開始執行時為其分配記憶體,程式結束執行時釋放其記憶體。相比於區域性變數的動態分配/釋放記憶體,全域性變數的生命週期長,而且當全域性變數數目較多時,會佔用較大的記憶體。
- 使用全域性變數會破壞函式的封閉性和獨立性。一個函式本來是通過傳參和返回值來進行輸入輸出,但是用了全域性變數之後,該函式就可以不僅只通過原有的引數和返回進行輸入輸出,這樣原有的封閉性就被破壞了,這也導致函式的可移植性降低。
- 當一個全域性變數多次被不同的語句(函式)操作,全域性變數的值容易變得不清晰,這便降低了程式的可讀性,不利於在編碼後進行除錯和查錯之類的操作。
- 區域性變數
優點:
- 區域性變數是程式動態分配記憶體的,所以生命週期短,不會造成長時間佔用過多記憶體的情況。
- 區域性變數定義在函式內部,限於函式內部呼叫,故能夠有效的保證函式的封閉性。
- 即使在多個函式內部定義了多個同名區域性變數,它們之間也不會相互影響。
缺點:
- 區域性變數中的資料在函式執行完後就會消失,故不利於資料的保留。
- 區域性變數的使用範圍有限,僅限於所屬函式的內部。