變量提升和函數(shù)提升是JS中最基本的知識,需要牢牢地掌握,用下面的例子簡單講一下變量提升和函數(shù)提升。
例子一
(function () {
console.log(a);
var a = 1;
function a() {
console.log('function a called');
}
console.log(a);
})();
// 先輸出:function a called
// 后輸出:1
這里輸出的是名為a的函數(shù),為什么是函數(shù)而不是undefined呢?這里需要記住這樣一句話:
函數(shù)提升優(yōu)先級高于變量提升,且不會被同名變量聲明時覆蓋,但是會被變量賦值后覆蓋。
這說明了函數(shù)是會先于變量進行提升的,所以會先聲明函數(shù)a,然后再去聲明變量a,但是聲明的時候變量a的undefined對函數(shù)a是無效的,它無法覆蓋,所以a依舊是function a。然后,當代碼執(zhí)行到a = 1的時候,就是正常的賦值語句,a會被覆蓋為1。
注意:變量提升(僅限于用var聲明的變量)和函數(shù)提升只作用于全局作用域和函數(shù)作用域中,ES6引入的let和const已經(jīng)提出必須先聲明才可以進行調用,否則會報錯。
例子二
(function () {
if (false) { //為true的時候會怎么樣?
function a() { console.log("this is function a") }
}
console.log(a);// 輸出: undefined
} ())
這里是一個立即執(zhí)行函數(shù)里面有一個條件判斷語句且為false里面包含了函數(shù)a的聲明,這時候要怎么理解呢?
- 當條件語句為true:則聲明函數(shù)a,且a會被提升到匿名函數(shù)作用域中進行聲明。
- 當條件語句為false:函數(shù)聲明會轉為函數(shù)表達式,即function a() {} => var a = function() {},a變量會有變量提升。
綜上,false的時候function a進行了變量a的提升,確沒能進行賦值,所以輸出為undefined。