什麼是提升(Hoisting)?

💡先講結論
在 JavaScript 中先賦予變數或函式一個記憶體空間的這個機制,就稱為 提升

在這之前先來談創造階段執行階段這兩個概念

  • 創造階段(Creation):瀏覽器為變數或是函式創造記憶體空間的階段。
  • 執行階段(Execution):瀏覽器將「值」賦予變數的階段。

1.先以下列程式碼為例子

var myName = '小白';
console.log(myName); //印出小白

/* 
    解釋上述程式碼的 創造階段 與 執行階段
    1. 創造階段:myName 變數「提升」,獲得一個記憶體空間,其值是 undefined
    2. 執行階段:myName 變數被賦予值,其值是'小白',console.log(myName) 會將 myName 變數中的值取出來後印出來
*/

2.修改一下順序

console.log(myName);
/* 
    這裡會印出 undefined!而不是 Uncaught ReferenceError: myName is not defined 的錯誤!!
    為什麼不會印出錯誤?myName 變數不是後面才宣告嗎?原因是因為 myName 變數「提升」了!
    在印出來之前,myName 變數已經有了記憶體空間,只是還沒被賦予值,因此是
unfedined
*/
var myName = '小白';

/* 
    1. 創造階段:myName 變數「提升」,獲得一個記憶體空間,其值是 undefined
    2. 執行階段:console.log(myName) 將 myName 變數中的值印出來 ( 印出 undefined )
                            myName 變數被賦予值,其值是'小白'。
*/


函式的創造階段執行階段,與變數相比多了兩個原則:

  • 函式在創造階段就已經有完整的記憶體空間
  • 函式陳述式優先函式表達式與變數宣告

1.舉例

callName();
// callName 函式在比較下面,理論上應該是沒辦法成功執行 callName(),
// 但是因為「提升」的機制,使得 callName 函式優先獲得記憶體空間,
// 因此你要在哪裡呼叫都可以!

// 下面函式的宣告方式叫做「函式陳述式」
function callName(){
    console.log('我是小明');
}
/* 
    解釋上述程式碼的創造階段與執行階段
    1. 創造階段:callName 函式優先「提升」,獲得一個記憶體空間
    2. 執行階段:呼叫了 callName() 函式,印出'我是小明'
*/

2.函式陳述式 v.s 函式表達式 ⇒ 兩者之間的差異在於「提升的方式」不同

//函式陳述式
function fn(){
    console.log('這是函式陳述式');
}

//函式表達式
var fn = function(){
    console.log('這是函式表達式');
}

fn();//呼叫 fn 函式,會印出 '這是函式陳述式' 還是 '這是函式表達式呢'?

/*
    這邊開始解釋「函式陳述式」與「函式表達式」的不同處,
    以上述程式碼為例,列出創造階段與執行階段
    1. 創造階段:
                            function fn(){ //函式陳述式優先提升
                                console.log('這是函式陳述式');
                            }
                            var fn; //fn 變數提升

    2. 執行階段:
                            fn = function(){ // fn 被賦予值
                                        console.log('這是函式表達式');
                                    }
                            fn(); //呼叫 fn 函式,最終印出'這是函式表達式'!!

    不同之處在於函式表達式會在執行階段才將值(整個function) assign 給 fn 變數,
    進而覆蓋了在創造階段出現的函式陳述式,所以才會印出'函式表達式'
*/
#javascript #變數與作用域







你可能感興趣的文章

python 筆記

python 筆記

淺談 ORM

淺談 ORM

JavaScript: Object-oriented JavaScript, Prototype Chain & This

JavaScript: Object-oriented JavaScript, Prototype Chain & This






留言討論