JavaScript變量提升

我們先提前預告一下變量提升的幾個要點,然后在根據(jù)后面的例子進一步闡述:

  1. 變量提升是按照作用域為單位的;
  2. 函數(shù)的提升優(yōu)先于變量的提升;
  3. 存在多個相同函數(shù)名的函數(shù)會被覆蓋;
  4. 函數(shù)表達式并不會被提升。

章節(jié)直通車:

什么是變量提升

可能有些小伙伴不清楚什么是變量提升,我們以一個簡單的例子來說明一下:

console.log( a );

var a = 2;

大家可以自己思考或者直接試驗一下,這里打印的a為undefined。

我們在第一章中說道編譯器的基礎三步驟,其一就是分詞、詞法分析,在此階段編譯器會把一些變量和相應的作用域進行關聯(lián),在作用域中提前聲明,我們可以把上面的代碼稍微變動如下:

編譯階段:

var a;

執(zhí)行階段:

console.log( a );

a = 2;

所以這時的a已經(jīng)被定義,輸出的時候就是undefined。這個就叫做變量提升。

變量提升是按照作用域為單位的

foo();

function foo() {
    console.log( a ); // undefined

    var a = 2;
}

在全局作用域中,foo函數(shù)被提升;
在foo函數(shù)中,變量a被提升。

console.log(c); // undefined

if (true) {
    var c = 1;
}

注意,if的大括號并不是作用域,所以這里的作用域還是全局作用域,變量c被提升了。(上一章節(jié)有具體介紹JavaScript作用域)

本來準備按照《你不知道的JavaScript》書中以if大括號和函數(shù)為例來說明,但是現(xiàn)在es6已經(jīng)改變了這種做法,在if條件中的函數(shù)會默認為函數(shù)表達式,函數(shù)表達式并不會被提升如下:

foo(); // "b"

var a = true;
if (a) {
   function foo() { console.log( "a" ); }
}
else {
   function foo() { console.log( "b" ); }
}

現(xiàn)在這里已經(jīng)不像書中說的輸出“b”了,而是undefined。

當然對于老版本這種操作也是非常不友好的,并不推薦使用,這里只是提一嘴。

函數(shù)的提升優(yōu)先于變量的提升

foo(); // 1

var foo;

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

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

上面很清晰的可以看到函數(shù)foo的聲明是優(yōu)先于變量的,否則會報錯TypeError。我們可以將上面的代碼修改為提升后的樣子:

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

// var foo; 由于上面foo已經(jīng)被聲明了,這一條就被直接過濾了

foo(); // 1

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

存在多個相同函數(shù)名的函數(shù)會被覆蓋

foo(); // 3

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

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

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

相關閱讀更多精彩內容

友情鏈接更多精彩內容