前言
Hoisting (提升) 整個過程都是與記憶體有關係,但實際 JavaScript 並沒有這個專有名詞存在
提升
執行環境其實可細分為兩個階段:創造環境及執行
我們可以先想像記憶體是成對的,左邊的格子表示 key ,而右邊是 value 。
創造環境做的事情是,把這段程式碼中所有變數挑出來,在記憶體中分配空間給這些變數,把變數的 key 放進來。
這個動作便稱為「提升 Hoisting」。在這個階段還不會給他值,所以如果在此時去取用這些變數的話,值會是undefined
為什麼變數會出現 undefined 呢?這個的原因在於 JavaScript 預先準備好記憶體時,必須先準備一個初始值所導致,因此若假使 JavaScript 沒有給予變數一個初始值,那麼就有可能出現錯誤,所以才會有 undefined 的存在。
接下來直到執行時,才會把值給塞進去
函式比變數有更高的優先權
前面所講的的範例是變數,那在這邊函式在宣告時,其實會比變數有更高的優先權,函式會比變數更優先被建立並放進記憶體中,但這邊僅限於函式陳述式
舉例以下這一個範例程式碼
var a = 'Bob';
function a() {
console.log('Hello');
}
console.log(a); // Bob
我們可以看到,明明函式是在變數之後被宣告,但出現的卻是 Bob,正常來講你或許會認為這邊應該要出現的是 function a() { … },但這邊前面有說過我們可以使用 Hoisting 的觀念來釐清其 JavaScript 運作原理,首先我們先區分出創造階段以及執行階段
創造階段
在前面有說過因為函式比變數有更高的優先權,所以會比變數更優先被建立
function a() {
console.log('Hello');
}
var a;
執行階段
a = 'Bob';
console.log(a); // Bob
透過上方範例可以了解到函式是比變數有更高的優先權被優先建立,但若函式沒有較高的優先權的話,那麼出來的就會不一樣。
此外因為函式會被優先建立的關係,因此你可以在函式之前呼叫該函式
sayHi(); // Hello Bob
function sayHi() {
console.log('Hello Bob');
}