1. 程式人生 > >JS中最經典的全域性變數和區域性變數問題(1、作用域和作用域鏈 2、變數宣告提前)

JS中最經典的全域性變數和區域性變數問題(1、作用域和作用域鏈 2、變數宣告提前)

var a = 10;
function test(){
    a = 100;
    console.log(a);
    console.log(this.a);
    var a;
    console.log(a);
}
test();

1、程式的執行結果為:100 10 100
解析:Javascript在執行前會對整個指令碼檔案的宣告部分做完整分析(包括區域性變數),從而確定變數的作用域,所以在函式test執行前,由於第6行聲明瞭區域性變數a,所以函式內部的a都指向已經宣告的區域性變數,所以第4行輸出100。第5行輸出this.a,我們都知道,函式內部的this指標指向的是函式的呼叫者,在這裡函式test被全域性物件呼叫,所以this指標指向全域性物件(這裡即window),所以this.a = window.a,一開始生命了全域性變數a=10,所以第5行輸出結果為10。第7行輸出結果為100,因為區域性變數a在第3行已經被賦值了100,所以直接輸出區域性變數a的值。

var a = 100;
function test(){
    console.log(a);
    var a = 10;
    console.log(a);
}
test();

2、程式的執行結果為:undefined 10
解析:看了第1個例子,可能有同學會認為輸出結果是10 10,但是結果卻不是10 10,為什麼呢?仔細看第1個例子解析的第一句話,Javascript在執行前會對整個指令碼檔案的宣告部分做完整分析(包括區域性變數),但是不能對變數定義做提前解析,在這個函式中,執行第3行前,可以認為已經聲明瞭變數a,但是並沒有定義(這裡即賦值),所以第3行輸出結果為undefined,執行第4行a =10後,變數a的值就為10,所以第5行輸出結果為10。

var a = 100;
function test(){
    console.log(a);
    a = 10;
    console.log(a);
}
test();
console.log(a);

3、程式的執行結果為:100 10 10
解析:我們知道在函式內部,一般用var宣告的為區域性變數,沒用var宣告的一般為全域性變數,在test函式內,a=10聲明瞭一個全域性變數,所以第3行的a應該輸出全域性變數的值,而在函式執行之前已經宣告過一個全域性變數並賦值100,所以這裡第上輸出100。第4行給全域性變數a 重新賦值10,所以全域性變數a的值變成10,所以第5行輸出10。而在函式test外部,第8行輸出全域性變數a的值,因為全域性變數被重新賦值為10,所以輸出結果即為10。

其實說來說去就2個問題:
1、作用域和作用域鏈
2、變數宣告提前