前言
第一篇文章主要是來介紹JavaScript的運作方式
JavaScript的運作方式
首先我們所撰寫JS程式碼,是沒有辦法直接被瀏覽器或電腦執行,需要透過轉譯器,將我們所撰寫的程式邏輯指令轉換成電腦看得懂的語言
舉個例子:
1 | var name = 'smalljie' |
上述的程式需要被轉譯器轉譯後才能在電腦執行
直譯語言 Interperted language
什麼是直譯語言? 這種類型的程式語言,會將程式碼一句一句直接執行,不像編譯語言一樣,需要經過編譯器先行編譯成機器碼,也就是翻譯成電腦看得懂的語言
直譯式語言的好處在於開發速度是比較快速且較彈性的,舉例來講 JavaScript 中我們可以不用預先定義型別,而是透過直譯器來動態辨別型別。
常見的代表性語言有
- Python
- JavaScript
- Ruby 等…
另外一種是編譯式語言,與上述的介紹一樣,需要透過編譯器進行編譯才能使用,直譯式語言與編譯式語言最明顯的差異在於直譯式語言必須先一條一條將程式碼讀取出來並透過直譯器轉換成機器碼才能夠被運作,所以通常來講直譯式語言的錯誤訊息都是直接呈現於開發環境上
編譯式語言最大特色在於,在我們撰寫程式碼的同時,他已經在預先編譯,所以當遇到問題時我們就可以預先除錯,那麼這就是編譯式語言的好處,通常來講效能也會比較好。
可是編譯式語言的壞處在於,你在開發時彈性會比較小且通常開發的速度以及 Debug 的時間是比直譯式語言較長
常見的代表性語言有
- C++
- C#
- Java 等..
JavaScript 直譯器轉換過程
先前有介紹過直譯式語言會依序一條一條將程式碼讀取出來並透過直譯器轉換成機器碼,而JavaScript在運行時會一個一個字去分析並解析出相對應的機器碼
舉個例子:
1 | var name = 'smalljie' |
當輸入上述程式碼時會先將所有的字詞,一個一個解析出來,比如先解析var,後解析name,其中標點符號也算字詞,這個步驟稱為語法基本單元化(Tokenizing),所以由此可知直譯器是會逐行逐字的去分析。
接下來語法基本單元化解析完畢後,會進入到抽象結構樹AST(Abstract Syntax Tree),來將整個程式碼定義完成,最後定義完成後會將程式碼轉換成機器碼
上述過程可以使用一個Esprima這個小工具來了解何謂語法基本單位化及抽象結構樹。
首先我們可以先在 Esprima 輸入以下程式碼
1 | function SayHi() { |
點選介面中Token分頁標籤,我們可以看到程式碼被一一分析成類似物件的結構,這就是所謂的語法基本單位化(Tokenizing)。
點選後會看到type有以下這些選項
- Keyword (關鍵字)
- Identifier (標識符,又稱為識別碼)
- Punctuator (符號)
- String、Number (型別)
在此要注意一件是,在語法基本單位化這個步驟時,他還不知道 function
是宣告一個函式,只是先將字詞解析出來而已。
勾選下方「Index-based range」及「Line and column-based」能夠看到相關的索引及行數。
接著會進入到Tree的階段,過程中我們可以了解到 JavaScript 的直譯器,是在 Tree 的階段才開始正式的了解每一個字詞的意義,例如會看到function
被宣告成函式,但是這邊 JavaScript 並還沒有開始真正的執行,只是了解他的字詞而已,真正的執行是在代碼生成的時候,但每一個執行環境的不同,所以執行的結果就會跟著不同。
這邊主要的重點在於抽象結構樹 AST(Abstract Syntax Tree)
這個階段時,程式碼是還沒有被運行的,實際運行是在代碼生成的時候。