簡單地說,JavaScript解析引擎就是可以「讀懂」JavaScript代碼,並準確地給出代碼運行結果的一段程序。比方說,當你寫了 var a = 1 + 1; 這樣一段代碼,JavaScript引擎作的事情就是看懂(解析)你這段代碼,而且將a的值變爲2。html
學過編譯原理的人都知道,對於靜態語言來講(如Java、C++、C),處理上述這些事情的叫編譯器(Compiler),相應地對於JavaScript這樣的動態語言則叫解釋器(Interpreter)。這二者的區別用一句話來歸納就是:編譯器是將源代碼編譯爲另一種代碼(好比機器碼,或者字節碼),而解釋器是直接解析並將代碼運行結果輸出。 比方說,firebug的console就是一個JavaScript的解釋器。算法
可是,如今很難去界定說,JavaScript引擎它到底算是個解釋器仍是個編譯器,由於,好比像V8(Chrome的JS引擎),它其實爲了提升 JS的運行性能,在運行以前會先將JS編譯爲本地的機器碼(native machine code),而後再去執行機器碼(這樣速度就快不少),相信你們對JIT(Just In Time Compilation)必定不陌生吧。瀏覽器
我我的認爲,不須要過度去強調JavaScript解析引擎究竟是什麼,瞭解它究竟作了什麼事情我我的認爲就能夠了。對於編譯器或者解釋器到底是如何看懂代碼的,翻出大學編譯課的教材就能夠了。閉包
這裏還要強調的就是,JavaScript引擎自己也是程序,代碼編寫而成。好比V8就是用C/C++寫的。函數
JavaScript引擎是一段程序,咱們寫的JavaScript代碼也是程序,如何讓程序去讀懂程序呢?這就須要定義規則。好比,以前提到的var a = 1 + 1;,它表示:性能
左邊var表明了這是申明(declaration),它申明瞭a這個變量spa
右邊的+表示要將1和1作加法操作系統
中間的等號表示了這是個賦值語句code
最後的分號表示這句語句結束了htm
上述這些就是規則,有了它就等於有了衡量的標準,JavaScript引擎就能夠根據這個標準去解析JavaScript代碼了。那麼這裏的 ECMAScript就是定義了這些規則。其中ECMAScript 262這份文檔,就是對JavaScript這門語言定義了一整套完整的標準。其中包括:
var,if,else,break,continue等是JavaScript的關鍵詞
abstract,int,long等是JavaScript保留詞
怎麼樣算是數字、怎麼樣算是字符串等等
定義了操做符(+,-,>,<等)
定義了JavaScript的語法
定義了對錶達式,語句等標準的處理算法,好比遇到==該如何處理
⋯⋯
標準的JavaScript引擎就會根據這套文檔去實現,注意這裏強調了標準,由於也有不按照標準來實現的,好比IE的JS引擎。這也是爲何JavaScript會有兼容性的問題。至於爲何IE的JS引擎不按照標準來實現,就要說到瀏覽器大戰了,這裏就不贅述了,自行Google之。
因此,簡單的說,ECMAScript定義了語言的標準,JavaScript引擎根據它來實現,這就是二者的關係。
簡單地說,JavaScript引擎是瀏覽器的組成部分之一。由於瀏覽器還要作不少別的事情,好比解析頁面、渲染頁面、Cookie管理、歷史記錄 等等。那麼,既然是組成部分,所以通常狀況下JavaScript引擎都是瀏覽器開發商自行開發的。好比:IE9的Chakra、Firefox的 TraceMonkey、Chrome的V8等等。
從而也看出,不一樣瀏覽器都採用了不一樣的JavaScript引擎。所以,咱們只能說要深刻了解哪一個JavaScript引擎。
搞清楚了前面三個問題,那這個問題就好回答了。我的認爲,主要途徑有以下幾種(依次由淺入深):
看講JavaScript引擎工做原理的書
這種方式最方便,不過我我的瞭解到的這樣的書幾乎沒有,可是Dmitry A.Soshnikov博客上的文章真的是很是的贊,建議直接看英文,實在英文看起來吃力的,能夠看譯本
看ECMAScript的標準文檔
這種方式相對直接,原汁原味,由於引擎就是根據標準來實現的。目前來講,能夠看第五版和第三版,不過要看懂也是不容易的。
看JS引擎源代碼
這種方式最直接,固然也最難了。由於還牽涉到了如何實現詞法分析器,語法分析器等等更加底層的東西了,並且並不是全部的引擎代碼都是開源的。
其實第一種方式中的文章,做者已經將文檔中內容提煉出來,用通俗易懂的方式闡述出來了。若是,看起來還以爲吃力,那說明還缺乏兩塊的東西:
對JavaScript自己還理解的不夠深刻
若是你剛剛接觸JavaScript,或者說之前甚至都沒有接觸過。那一會兒就想要去理解內部工做原理,的確是很吃力的。首先應該多看看書,多實踐實踐,從知識和實踐的方式來了解JavaScript預言特性。這種狀況下,你只須要了解現象。比方說,(function(){})() 這樣能夠直接調用該匿名函數、用閉包能夠解決循環中的延遲操做的變量值獲取問題等等。要了解這些,都是須要多汲取和實踐的。實踐這裏就很少說了,而知識汲取方面能夠多看看書和博客。這個層面的書就相對比較多了,《Professional JavaScript for Web Developers》就是本很好的書(中文版請自行尋找)。
缺少相應的領域知識
當JavaScript也達到必定深度了,可是,仍是看不大明白,或者無法很深刻到內部去一探究竟。那就意味着缺乏對 應的領域知識。這裏明顯的就是編譯原理相關的知識。不過,其實對這塊瞭解個大概基本看起來就沒問題了。要再繼續深刻,那須要對編譯原理了解的很深刻,好比 說詞法分析採用什麼算法,通常怎麼處理。會有什麼問題,如何解決,AST生成算法通常有哪幾種等等。那要看編譯原理方面的書,也有基本經典的書,好比《Compilers: Principles, Techniques, and Tools》這本也是傳說中的龍書,還有很是著名的《SICP》和《PLAI》。 不過其實根據我的經驗,對於Dmitry的文章,要看懂它,只要你對JavaScript有必定深度的瞭解,同時你大學計算機的課程都能大體掌握了(尤爲 是操做系統),也就是說基礎不錯,理解起來應該沒問題。由於這些文章基本沒有涉及底層編譯相關的,只是在解釋文檔的內容,而且其中不少東西都是相通的,比 如:context的切換與CPU的進程切換、函數相關的的局部變量的棧存儲、函數退出的操做等等都是一致的。