iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 15
0
自我挑戰組

你為什麼不問問神奇 JavaScript 呢?系列 第 15

Day15 - 何謂範疇?

程式語言到底是如何讓電腦操作的?
這章節都是背後做的事情,另外用自己的想法寫了同一篇故事。
請多多指教。

編譯器理論

JavaSctipt 實際上是一種編譯式語言 ( compiled language ),但並非早先編譯好,所以無法在各個分散式系統間移植。

但他還是會經歷三個步驟:

  1. Tokenizing ( 語法基本單元化 ) 與 Lexing ( 語彙分析 )。
  2. Parsing ( 剖析,或語法分析 )
  3. Code-Generation ( 產生目的程式碼 )

就 Tony 的理解,以 var a = 2; 為例。

  1. 找出單字。
    var, a, =, 2, ;, (空白)(空白為選擇性,有有意義才會放。)

  2. 把單字組成的句子,進行文法分析。
    var a = 2; 的抽象語法樹 ( grammatical structure )。他會把句子架成下面的結構。
    https://ithelp.ithome.com.tw/upload/images/20181030/20112096CGLB0ytxGk.png

  3. 轉成機器看得懂的指令。 ( a set of machine instructions )

JavaScript 進行的工作複雜很多。還有最佳化 ( optimize ) 執行效能的步驟,舉例:消除多餘元素。

但花時間很少,因為馬上編譯馬上執行。

卡司

  • Engine 引擎
    老闆,開始到結束編譯過程,到執行我們的 JavaScript 程式。

  • Compiler 編譯器
    工廠,處理剖析,並產生程式碼。

  • Scope 範疇
    倉庫,負責收集並維護由所有已宣告的識別字。所構成的查找清單。

前後往返 ( Back and Forth )

var a = 2; 是一個述句。

Engine 看到的兩個不同的述句。
(但對老闆來說是兩件事,確認有沒有庫存空間,和把東西塞進去。)

  1. var a 工廠會問問看倉庫是否有放 a 的空間,如果有,就用原本的 a。如果沒有,就請倉庫生一個。
  2. 工廠會產生請老闆使用的產品,來處理 a = 2 的指定式。老闆會問倉庫有沒有 a 的空間可以放東西,如果有,就放著。如果沒有,就會往更大的倉庫問。(大倉庫會包著小倉庫)

如果最大的全球倉庫都沒有空間,老闆就會罵人了。

compiler (工廠) 說話了

經過第二件事,老闆 Engine 的查詢會有兩種。

如果變數在等號的左邊 => LHS ( lefthand side )
就是找倉庫有沒有空間放東西

變數在等號的右邊 => RHS ( righthand side )
就是找出倉庫裡面的東西。

function foo(a) {
    console.log( a ); // 2
}
foo(2);
  1. 調用 foo(..) 找到 foo(a) => RHS
  2. a = 2 => LHS,隱含的指定
  3. console.log() 會找 console => RHS
  4. 透過 屬性解析 ( property resolution ),查找是否有 log 屬性。
  5. 最後,把 2 傳到 log(..) 時,會有一次 LHS/RHS 的交換。( 大意是,這不是 Tony 想的單純的 RHS。 )

Engine 與 Scope 的對話

這邊就不搬書了,可以套用老闆跟倉庫講話,問他有沒有東西拿 ( RHS ),和有沒有空間放 ( LHS )。

巢狀範疇

倉庫外的大倉庫,就像是氣球外面包氣球。

如果小倉庫沒有東西拿,就會去大倉庫拿,直到全球總倉。

錯誤

為什麼區分 找位置 LHS拿東西 RHS 這麼重要?

因為倉庫如果沒有把位置的空間留下來,兩個的行為會不同。

function foo(a){
    console.log( a + b );
    b = a;
}
foo( 2 );

當要在 b 拿東西拿不到! 就會稱為一個「未宣告 undeclared」的變數,因為倉庫找不到這個空間,更不用說有東西在裡面。 ReferenceError。

但如果是要找空間 LHS,沒有沒關係,倉庫幫你生一個。
但是,在嚴格模式 ( strict mode ),倉庫就不能自動幫你生了。在這模式下,就會得到 ReferenceError。

如果你拿東西時 ( RHS ),想從方的位置拿出圓的東西,或是圓的位置拿出方的東西。你會得到 TypeError。

結論

寫這篇的時間花得比想像中的還多。
主要是定角,反覆看了一下,還是沒有很完美。
如果有其他更好的建議,請來多多交流。

明天見~

參考資料

你所不知道的JS


上一篇
Day 14 - 錯誤訊息
下一篇
Day16 - 語彙範疇
系列文
你為什麼不問問神奇 JavaScript 呢?30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言