關(guān)于JavaScript變量提升那點事兒

ECMAScript在瀏覽器端運行被稱為JavaScript

在瀏覽器端JavaScript是一種描述型腳本語言,不需要編譯成中間語言,而是由瀏覽器按代碼塊順序進(jìn)行動態(tài)地解析與執(zhí)行。

關(guān)于作用域

ES6之前,只有全局作用域和函數(shù)作用域;ES6引入了塊級作用域。作用域是代碼執(zhí)行過程中的變量、函數(shù)或者對象的可訪問區(qū)域。

  • 全局作用域:當(dāng)定義變量的地方?jīng)]有被 function 包括則是全局變量
  • 函數(shù)作用域:在函數(shù)內(nèi)部定義的變量就是處于函數(shù)作用域中
  • 塊狀作用域:類似于 if、switch 條件選擇或者 for、while 這樣的循環(huán)體即是所謂的塊級作用域

關(guān)于變量的生命周期

變量的生命周期包含著變量聲明、變量初始化、以及變量賦值三個步驟;其中聲明步驟會在作用域中注冊變量,初始化步驟負(fù)責(zé)為變量分配內(nèi)存并且創(chuàng)建作用域綁定,此時變量會被初始化為 undefined,最后的分配步驟則會將開發(fā)者指定的值分配給該變量。

關(guān)于預(yù)編譯

JavaScript代碼不需要編譯成一個其它可執(zhí)行的文件,但是js代碼在執(zhí)行之前會有一個準(zhǔn)備過程,這個準(zhǔn)備過程叫作預(yù)編譯。
預(yù)編譯的過程是不可見的,也不會產(chǎn)生額外的文件。

預(yù)編譯期間會主要完成兩件事情:

  1. 按順序掃碼代碼塊,如果發(fā)現(xiàn)語法錯誤,停止工作并報錯;
  2. 若沒有語法錯誤,做聲明變量和初始化變量的操作即所謂的變量提升操作;

先看一道簡單的題目

<script type="text/javascript">
    console.log(a);
    var a = 666;
    console.log(a);
</script>  

這道題目很簡單,但是卻很能說明問題。

提升操作

  • 使用var聲明的變量的提升:把所有帶有var關(guān)鍵字的變量名,提升到當(dāng)前代碼塊的開始,并設(shè)初值為undefined。
  • 函數(shù)提升:把所有用聲明式定義的函數(shù),提升到當(dāng)前代碼塊的開始,注意是做函數(shù)整體的提升。

具體細(xì)節(jié)如下

只提升加var的變量,沒有var不提升


如圖,沒有var,變量名沒有提升,相當(dāng)于沒有聲明變量a就直接使用它,會出現(xiàn)引用類型錯誤。

if結(jié)構(gòu)中的變量提升


如圖所示,變量提升一定是發(fā)生在預(yù)編譯期(提升之后才會進(jìn)入代碼的執(zhí)行期),而變量的提升與if條件語句是否成立無關(guān)。只要有var就會提升。

for循環(huán)中的變量提升


同樣會做變量提升。

函數(shù)內(nèi)部的變量提升


函數(shù)內(nèi)部定義的變量,不可能提上到函數(shù)的外部。如圖會直接報錯。

函數(shù)內(nèi)部的變量只會體升到函數(shù)的開始位置。

只提升聲明式定義的函數(shù)

定義函數(shù)有兩種方式:

  • 聲明式:function f(){}
  • 函數(shù)表達(dá)式: var f = function(){}


函數(shù)提升是整個函數(shù)體提升,變量提升是提升的變量名。

如上圖所示,通過表達(dá)式定義的函數(shù)提升,報了一個TypeError的錯誤;是因為預(yù)編譯期將var關(guān)鍵字提升,也就是說這里的f就是一個普通變量,它的初值被賦為undefined;當(dāng)代碼執(zhí)行到第11行f();時就相當(dāng)于是undefined();,所以肯定會報類型錯誤。

函數(shù)與變量同時提升


當(dāng)函數(shù)名與變量名同名,且同時提升,以函數(shù)為準(zhǔn)。
理由是函數(shù)是一等公民,地位高于變量。

提升不能跨script標(biāo)簽

開始那道題的答案

ES6中的變量提升以及暫時性死區(qū)

在 ES6 中以 let 與 const 關(guān)鍵字聲明的變量會在作用域頭部被初始化,不過這些變量僅允許在實際聲明之后使用。在作用域頭部與變量實際聲明處之間的區(qū)域就稱為所謂的暫時死區(qū)(Temporal Dead Zone),TDZ 能夠避免傳統(tǒng)的提升引發(fā)的潛在問題。

小結(jié)

以上,就是關(guān)于JavaScript變量提升的知識小結(jié)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容