JavaScript很酷(不要@我),可是機器如何才能真正理解您編寫的代碼?做爲JavaScript開發人員,咱們一般沒必要本身處理編譯器。可是,必定要了解JavaScript引擎的基礎知識,看看它如何處理咱們人類友好的JS代碼,並將其轉變爲機器能夠理解的東西!🥳javascript
| 注意: 這篇文章主要基於Node.js和基於Chromium的瀏覽器使用的V8引擎。java
HTML解析器遇到script帶有源的標記。來自script的代碼從網絡,緩存或已安裝的service worker
中加載。請求腳本做爲一個字節流被響應,該字節流被字節流解碼器
處理!字節流解碼器對字節流進行解碼,一旦它被下載。git
字節流解碼器從解碼的字節流中建立token
。例如,0066解碼爲f, 0075解碼爲u, 006e解碼爲n,0063解碼爲c, 0074解碼爲t,0069解碼爲i, 006f解碼爲o和 006e解碼爲n後跟一個空格。好像你寫function
同樣!這是JavaScript中的保留關鍵字,建立token
並將其發送到解析器(和pre-parser,我沒有在gif中介紹,但稍後會進行解釋)。其他字節流也會發生一樣的狀況。github
引擎使用兩個解析器:預解析器
和解析器
。預解析器僅及早檢查token
,以查看是否存在語法錯誤❌。這樣能夠減小發現代碼中錯誤的數量,不然解析器稍後會發現錯誤!瀏覽器
若是沒有錯誤,則解析器根據從字節流解碼器接收的token
建立節點。使用這些節點,它會建立一個抽象語法樹或AST。🌳緩存
接下來,是時候翻譯了!翻譯器
(interpreter)遍歷AST,並根據AST包含的信息生成字節碼
。字節代碼生成完畢後,將刪除AST,以清除內存空間。最後,咱們有一些機器能夠使用的東西!🎉網絡
儘管字節碼很快,可是能夠更快。運行此字節碼時,將生成信息。它能夠檢測某些行爲是否常常發生,以及所使用的數據類型。也許您已經調用了數十次函數:是時候對其進行優化,使其運行得更快了!♀♀️函數
字節碼與生成的類型反饋一塊兒被髮送到優化編譯器
(optimizing compiler)。優化編譯器獲取字節碼和類型反饋,並從中生成高度優化的機器碼。🚀oop
JavaScript是一種動態類型化的語言,這意味着數據類型能夠不斷變化。若是JavaScript引擎每次必須檢查某個值具備哪一種數據類型,那將很是慢。post
相反,引擎使用一種稱爲內聯緩存
(inline caching)的技術。它將代碼緩存在內存中,以期未來返回具備相同行爲的相同值!假設某個函數被調用了100次,而且到目前爲止一直返回相同的值。它將假定它也會在您第101次調用它時返回該值。
假設咱們有如下函數sum,到目前爲止,每次都使用數值做爲參數來調用它:
這將返回數字3!下次調用它時,它將假定咱們再次使用兩個數值調用它。
若是是這樣,則不須要動態查找,它能夠使用存儲在已引用的特定內存插槽中的結果。不然,若是假設不正確,它將不會對代碼進行優化,而且恢復爲原始字節代碼,而不是優化後的機器代碼。
例如,下一次調用它時,咱們傳遞的是字符串而不是數字。因爲JavaScript是動態類型的,所以咱們能夠作到這一點而沒有任何錯誤!
這意味着該數字2將被強制轉換爲字符串,而該函數將返回該字符串 "12"。返回執行解釋的字節碼並更新類型反饋。
但願這篇文章對您有用!😊固然,我在這篇文章中沒有涉及引擎的許多部分(JS堆,調用堆棧等),我稍後可能會涉及!若是您對JavaScript的內部結構感興趣,我絕對鼓勵您本身開始作一些研究,V8是開源的,而且有一些很好的文檔說明了它的幕後工做方式!🤖
V8文件 || V8 Github || Chrome University 2018:腳本人生
本系列包括6篇文章