一些語言如C、java都有塊級範圍,即花括弧內的每一段代碼都具有各自的範圍,而且變數在聲明它們的程式碼片段之外是不可見的,但是javascript沒有塊級範圍。javascript使用函數範圍,即變數在聲明它們的函數體以及這個函數體嵌套的任意函數體內都是有定義的,也即函數內聲明的所有變數在函數體內始終是可見的。這樣就意味著變數在聲明之前就可以使用,這個特性被稱為"聲明提前",即javascript函數裡聲明的所有變數都被提前至函數的頂部。來看個例子。
複製代碼 代碼如下:
var test1 = "globalVariable";
function test(){
console.log(test1);
var test1 = "localVariable";
console.log(test1);
}
上述函數執行的結果是:先輸出"undefined",再輸出"localVariable"。
很多人都會誤以為結果是:先輸出"globalVariable,再輸出localVariable"。其實不然,由於函數範圍的特性,局部變數在整個函數體始終是有定義的,也即,在函數體內局部變數遮蓋了同名全域變數,但是只有在程式執行到var語句的時候,局部變數才會被真正的賦值。因此,上述過程相當於,將函數內的變數聲明提前至函數體頂部,同時變數初始化留在原來的位置。就相當於如下這個函數
複製代碼 代碼如下:
var test1 = "globalVariable";
function test(){
var test1; //將函數內的變數聲明提前至函數頂部
console.log(test1);
test1 = "localVariable"; //賦值
console.log(test1);
}
但是,如果函數內沒有用var聲明變數,情況又有所不同。
複製代碼 代碼如下:
var test1 = "globalVariable";
function test(){
console.log(test1);
test1 = "localVariable";
console.log(test1);
}
這個函數執行的結果是:先輸出"globalVariable",再輸出"localVariable"。
由於函數體內的test1變數沒有用var聲明,就預設為全域變數,當然就不存在變數提前聲明的問題。第一行就會輸出"globalVariable",而第三行改變了test1全域變數的值,輸出了"localVariable"。