JavaScript 核心觀念(1)-JavaScript是如何運行的呢? (直譯語言、編譯語言的差異)

哈囉大家好,我是Kris

今天要來分享課程中的第一堂課-JavaScript如何運行以及直譯語言與編譯語言的差異在哪裡


因為電腦無法直接看懂原始碼,也就是我們工程師所撰寫出來的程式碼

所以會經過一些處理來讓電腦瞭解以後再去運行。


直譯語言和編譯語言的差異

直譯語言:執行前未經編譯,像是JavaScript就是直譯語言哦。

好處:彈性比較高、不需要預先定義型別。

*錯誤會直接反映在環境中,ex:chrome裡的console


編譯語言:會預先編譯再運行。

好處:預先編譯就可以預先除錯、語言效能比較好。


*大多時候我們在說某種語言為編譯或直譯語言時,指的是【大多數】並非全部。

就像是我們說JavaScript是直譯語言,不代表JavaScript不能有編譯器,反之亦然。



JavaScript直譯器轉換過程



語法基本單元化(Tokenizing):將JS裡的標點符號、詞彙先分別解析出來。   *JS=JavaScript

抽象結構樹AST(Abstract Syntax Tree):將整個原始碼的結構定義出來。

代碼生成:最後一步才會生成代碼。

生成出來的代碼會根據環境的不同稍微有不一樣的地方。

*在結構樹的階段尚未運行程式碼


可以利用這個網站來更深入的瞭解整個轉換過程👇

https://esprima.org/demo/parse.html#

接下來操作並解釋給大家看

首先在左側輸入程式碼 var 變數 = '內容'; 這邊我輸入的是【var ming = '小名';】




右側的頁籤選到Tokens,可以看到拆成了各個不同的標點符號以及詞彙。
Keyword是關鍵字,內容(value)為"var";Punctuator是標點符號。

有點像小時候寫作文時,需要先瞭解各個詞語的意思以及不同的標點符號代表什麼意思,
Tokenizing就是在做這樣子的事情,先拆開分類但還不會瞭解我們是在定義一個變數。


點選最左側:結構樹Tree
轉換成電腦看得懂的方式,Tree有點像是JSON格式。


VariableDeclarator:定義一個變數
kind:定義變數的方法是var
Identifier:變數的字詞;name:內容是ming
然後把'小名'這個詞彙賦予進變數。

到這裡才會知道我們正在定義一個變數。
目前這個步驟只是把結構定義出來,但是尚未執行!在代碼生成之後才會執行。


額外補充

沒有使用var、let來宣告變數的話會變成全域變數。
透過結構樹來瞭解兩者是完全不同的結果。
沒有使用var、let宣告時,用的是AssignmentExpression是一個assign的表達式
是直接把'小名'這個詞附在ming變數上面,根本沒有做宣告的動作。
可以透過這個方法,來瞭解在JS是宣告了一個變數或者是賦予一個值而已。

額外補充二

使用var宣告變數時,如果不在特定的範疇,則為全域變數。
使用var跟不使用var都可能是全域變數,那到底差別在哪裡呢?

有無宣告 var是有很大的差異,最大差異在於「該變數可不可以被刪除」

如果你沒有使用 var 宣告變數,那麼就會被當作物件新增進入到 window 底下,
此時你就可以使用 delete 語法刪除該屬性(delete 是刪除物件屬性的方法)
c = 1;
delete c; // 成功刪除

所以若用了 var 宣告變數之後,那麼就無法透過 delete 刪除。

var c = 1;
delete c; // 失敗;無法刪除

所以這邊的重點觀念在於 「window 是一個物件,若不透過 var 宣告變數,那麼就會被當作物件新增」。


好~今天就到此告一段落
期許自己持續努力,成為更好的人。
大家一起努力💪💪💪

评论

此博客中的热门博文

JavaScript 核心觀念(5)-執行環境(Execution context)與執行堆疊(Execution stack)

JavaScript 核心觀念(7)-執行環境與作用域-提升Hoisting

JavaScript 核心觀念(6)-執行環境與作用域-範圍鍊