05 JS 聲明提升

關(guān)于編譯器,引擎會(huì)在解釋 JS 代碼之前首先對(duì)其進(jìn)行編譯。編譯階段的一部分工作就是找到所有的聲明,并用合適的作用域?qū)⑺鼈冴P(guān)聯(lián)起來(lái)。

1.聲明提升

“提升”就是變量和函數(shù)聲明從它們?cè)诖a中出現(xiàn)的位置被“移動(dòng)”到了最上面,這個(gè)過(guò)程就叫“提升”。

// 代碼示例 1
foo();
function foo() {
    console.log(a); // undefined
    var a = 2;
}

如上面代碼示例 1, foo 函數(shù)的聲明被提升了,因此第一行中的調(diào)用可以正常執(zhí)行。需要注意的是,每個(gè)作用域都會(huì)進(jìn)行提升操作。也就是函數(shù)自身也會(huì)在內(nèi)部對(duì) var a 進(jìn)行提升,所以最終的形式可以理解為如下代碼示例 2:

// 代碼示例 2
function foo() {
    var a;
    console.log(a); // undefined
    a = 2;
}
foo();

2.函數(shù)表達(dá)式不會(huì)被提升

// 代碼示例 3
foo(); // TypeError 類(lèi)型錯(cuò)誤

var foo = function bar() {
     // ...
}

foo() 由于對(duì) undefined 值進(jìn)行函數(shù)調(diào)用而導(dǎo)致非法操作,因此拋 TypeError 出異常。

3.函數(shù)優(yōu)先

函數(shù)聲明會(huì)被提升到普陀變量之前。

// 代碼示例 4
foo(); // 1

var foo;

function foo() {
    console.log(1);
}

foo = function() {
    console.log(2);
}

上述代碼示例 4 會(huì)被引擎理解為如下形式:

function foo() {
    console.log(1);
}

foo();  // 1

foo = function() {
  console.log(2);
}

重復(fù)的函數(shù)聲明可以覆蓋前面的。

盡可能避免在塊內(nèi)部聲明函數(shù)。

總結(jié)

  • var a = 2; 其中 var a; 是編譯階段的任務(wù),a = 2; 是執(zhí)行階段的任務(wù);
  • 所有的聲明(變量和函數(shù))都會(huì)被“移動(dòng)”到各自作用域的最頂端,這個(gè)過(guò)程叫“提升”;
  • 聲明本身會(huì)被提升,而包含函數(shù)表達(dá)式在內(nèi)的賦值操作不會(huì)被提升;
  • 避免重復(fù)聲明。

注:文章參考總結(jié)自 《你不知道的 JavaScript 上卷》[美] KYLE SIMPSON 著 第 42 頁(yè)。

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

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

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