轉生第二十三日,接下來這一篇將會介紹 Hoisting。
首先前面這邊先大概提一下 JavaScript 的運作流程
window
window
及 this
關於語法解析器可以參考我先前寫的其他文章:[JS奇怪的世界]No.1 觀念小提醒:語法解析器、執行環境、詞彙環境
那什麼是 Hoisting 呢?Hoisting 可以細分主要兩個階段
前面我們知道一開始 JavaScript 在執行環境會優先建立 window
與 this
,接下來就會開始進入 Hoisting 的兩階段,舉例來講,我們目前所撰寫的程式碼如下:
a();
function a() {
console.log('函式 A');
}
var b = 1;
當 JavaScript 讀取完我們所有的程式碼就會開始依序準備相關記憶體,那麼如果我們直接將程式碼貼到系統內執行,其實你會發現一件很奇妙的事情,也就是我明明是在函式之前呼叫函式,但卻不會出現錯誤,反而還能夠正常呼叫 ↓
那這個原因最主要是出在 JavaScript 的 Hoisting 特性所導致,程式碼在運行時,會被劃分為兩階段,第一階段是創造並提升函式與變數,然後第二階段則是執行程式碼,但是這邊有一個重點要記得函式比變數有更高的優先度,所以會被提升至比變數更前面,所以實際運行的程式碼是像這樣:
// 創造 & 提升階段
function a() {
console.log('函式 A');
}
var b;
// 執行階段
a();
b = 1;
所以我們可以知道一件事情,JavaScript 在執行時會先經歷過 Hoisting 的兩階段,最後才會在執行階段將相關的變數賦予值或是執行其他動作,另外 Hoisting 在 MDN 的文件上有解釋,以下擷取 MDN 片段
提升看起來是單純地將變數和函式宣告,移動到程式的區塊頂端,然而並非如此。變數和函數的宣告會在編譯階段就被放入記憶體,但實際位置和程式碼中完全一樣。
所以由此可知 Hositing 會跟記憶體有關係,因為 JavaScript 在執行前,會先將變數和函式提升至最前面並儲存在記憶體中,後面再依照相對應做賦值或處理,但是並不會將程式碼改變位子唷~
下一篇的 RE:從零開始的學習 JS 生活-第二十四日 將會介紹 undefined 與 not defined 的差異。
本文同步發表於:https://hsiangfeng.github.io/javascript/20191008/4283554681/
語法解析器開始分析我們的程式內容,例如 f-u-c-t-….(逐字解析...)
我本來以為是要寫 fuxk,後來才發現原來是想說 function 這個例子 XD
我絕對不會這樣寫