先來一個小小的例子吧
a = 2;
var a;
console.log(a); //2
不是打印 undefined 而是打印 2
這是因為使用var聲明的變量是全局性的,存在變量提升。那什么是變量提升呢?
js并不是嚴格的自上而下的語言,瀏覽器編譯js的時候,會把用var聲明的變量提到所有代碼前面。然后再執(zhí)行代碼。
所以上面的代碼就等同于
var a;
a = 2;
console.log(a); //2
但是變量提升只提升聲明,不會提升賦值。就像下面這個例子一樣
console.log(a) //undefined
var a=2
因為var a=2在瀏覽器解析中是分成這樣的兩步。var a被提升了,但是a=2還在console后面
var a;
a=2
js除了變量提升,還存在函數(shù)提升
函數(shù)聲明格式:
function 函數(shù)名 (參數(shù)){
// 函數(shù)體
}
只有使用這種格式聲明的函數(shù),才會被函數(shù)提升,并且比變量提升位置更加靠前(即同名情況下,給function使用)
變量提升的基本規(guī)則:同名情況下,后面的函數(shù)聲明會覆蓋前面的函數(shù)聲明
看下面一個例子
foo()
var foo = function () { // 這種格式叫做函數(shù)表達式
console.log("foo")
} //報錯,foo is not a function
經(jīng)過函數(shù)提升以后,上面的這段代碼變成:
var foo
foo()
foo = function () {
console.log("foo")
}
所以會報錯,foo is not a function。
又一個例子
foo();
function foo() {
console.log('foo');
}
var foo = 2;
上面的代碼,最后會打印 foo。(不存在我們以為的,后聲明的會覆蓋前面的聲明,打印出foo is not a function)
最后補充一下:
a=2
console.log(a) // 2
可以打印a的值,這是因為不寫出聲明方式的話,默認是全局變量,用var聲明。