[筆記] Javascript 基礎概念
Javascript engine, runtime, optimized code, call stack & memory heap
筆記整理來自於以下課程的內容:
How Javascript works?
- JS 檔案需透過 Javascript Engines 轉換成電腦可讀取的機器語言(0與1)。
- Javascript Engines 的作用:在符合 ECMAScript 規範下,使用 lexical analysis (詞法分析) 拆解成 token (代表執行某些操作的權利的物件) 去理解各個指令的作用, 並組成 AST (abstract syntax tree, 抽象語法樹),後經過編譯器+直譯器 (JIT compiler/Just In Time compiler) 轉換成電腦語言,使其能有效率地呈現在瀏覽器上。
- Javascript Engines 會在你的 JS 程式碼直譯前先編譯它,位元組碼 (Bytecode) 通常指的是已經經過編譯,需要直譯器轉譯後才能成為機器碼的中間代碼。
- Babel & TypeScript:常見於前端使用的 Javascript 編譯器
Two ways to optimized (優化) code
- inline caching (內聯快取):
- 在執行過程中,收集型別資訊,讓引擎在後續執行過程中利用這些型別資訊作出預判,每次呼叫物件上的方法或屬性的時候先查詢快取,如果命中則直接使用快取結果。如果未命中,就查詢隱藏類來獲取結果。
- 如下例,若 userData 被呼叫多次,則會直接使用第一次獲得的結果 - 快取資料 'found Hoodie Cat',而不會再去照:查詢物件 userData -> firstName 屬性,這樣的順序去執行
- hidden classes (隱藏類別) 機制:
- 在初始化物件的時候引擎會建立一個隱藏類別,隨後在程式執行過程中每次增減屬性,就會建立一個新的隱藏類別,或者查詢之前已經建立好的隱藏類別,不同初始化順序的物件,所生成的隱藏類別是不一樣的。
- 如下例,obj1 依照 a -> b 這個順序在物件裡添加兩個屬性,obj2 若反過來以 b ->a 順序建立,則會被建立不同的隱藏類別,而減慢了程式查找、執行的速度。
Call stack and Memory Heap
- Stack 與 Heap 都是在記憶體上組織資料的方式。
- Call stack (呼叫堆疊):JavaScript 是以單執行緒 (single threaded) 的方式進行 (一次執行一個指令或函式),call stack 則是等待執行的任務會放入一個堆疊,追蹤並依序執行所有的過程。
- Memory Heap:用來存放並且管理程式全部所需要用到的變數與資料。
- JavaScript 中含有垃圾回收器 (garbage collector) 的系統:追蹤記憶體分配的使用情況,以便自動釋放一些已經不受任何參考 (reference-counting) 的記憶體空間,避免 “ memory leaks (記憶體流失) ”,但有其判斷上的限制,故工程師仍須注意記憶體控管。
Javascript Runtime
- Runtime 指的是在執行時提供 Global Object 給 JS Engine,讓它有能力與執行環境互動:
- Javascript engine 執行 call stack 中的任務。
- 當遇到 Web APIs 或是無法處理的任務時會交給 Javascript runtime 執行,處理完成後將資料交給 callback function,並將 callback function 放進 queue 中,形成 Callback Queue。
- 事件迴圈 (Event loop) 會持續確認 call stack 中的任務,當全部執行結束變成空的時候,就從 callback queue 中拉取第一個任務放進 call stack,回到第一步繼續重複循環下去 [實例展示]。
- 在 Browser 環境中 Runtime 就是 Web APIs。
- 在 Node.js 中則是 Global API,並將環境建置於 Browser 外,使其能與電腦上的檔案互動等其他瀏覽器所無法操作的功能。
Synchronous vs Asynchronous
- 同步 (Synchronous) 指的是程式碼的執行順序是由上往下一行一行的執行,同一時間只能做一件事,也就是上一行的程式如果沒有執行完就會卡住下一行程式的執行造成阻塞 (blocking),導致後面的程式都無法執行,如果遇到複雜的數學運算或是需要大量 CPU 運算的任務時就會嚴重影響程式的運作。=> Javascript Engine
- 非同步 (Asynchronous) 指的是會先將工作丟出去給其他執行環境(Runtime)處理,不阻塞 (non-blocking) 後續程式的執行,處理完成後再將結果傳給回調函式 (callback function),然後等待 Event Loop,例如 AJAX ,或是讀檔寫檔這種存取外部資料的 I/O 都是常見的非同步行為。=> Javascript Runtime