何為JavaScript引擎,帶你揭開它神秘的面紗
發布時間:2021-09-03 10:58:29 已幫助:74人
何為JavaScript引擎,帶你揭開它神秘的面紗
javascript是編程語言的一種,這個我相信很多人是知道的。但是他具體如何使用,能實現什么功能,就可能很少有人清楚了。
現在很多人認為java和javascript能做的差不多,就更是一種非常錯誤的認識。
最初,JavaScript只能在Web瀏覽器中運行,但是隨著Node的出現,現在JavaScript也可以在服務端運行。雖然我們可能知道應該在何時何地去使用它,但是我們真的了解這些腳本執行的背后發生了什么嗎?
如果您覺得自己對JavaScript引擎有了一些了解的話,可以先給自己鼓個掌,但不要急著關掉本文,我相信閱讀完成后您仍然可以從中學到一些東西。
JavaScript是一門高級語言,但是最終計算機能理解只有1和0。那么我們編寫的代碼是如何被計算機理解的呢?掌握所學編程語言的基礎知識將讓您能編寫出更好的代碼。在本文中,我們僅探討一個問題:JavaScript是如何的?
下面讓我們進入正題~
JavaScript引擎
這是本文將要探索的主要內容,它負責使計算機理解我們編寫的JS代碼。JavaScript引擎是一種用于將我們的代碼轉換為機器可讀語言的引擎。如果沒有JavaScript引擎,您編寫的代碼對計算機來說簡直是一堆“胡言亂語”。不僅僅是JavaScript,其他所有編程語言都需要一個類似的引擎,來將這些“胡言亂語”轉換成對計算機有意義的語言。
目前有多種JavaScript引擎在可供使用。您可以在Wikipedia上查閱所有可用的JavaScript引擎。它們也被稱為ECMAScript引擎,這樣叫的具體原因會在下文中提及。下面是一些我們日??赡軙玫降腏avaScript引擎:
·Chakra,Microsoft IE/Edge
·SpiderMonkey,FireFox
·V8,Chrome
除此之外的其它引擎,可以自行搜索了解。接下來,我們將深入研究這些引擎,以了解它們是如何翻譯JavaScript文件的。
我們已經知道了引擎是必須的,由此可能不禁會想:
是誰發明了JavaScript引擎?
答案是,任何人都可以。它只是分析我們的代碼并將其翻譯的另一種語言的工具。V8是最受歡迎的JavaScript引擎之一,也是Chrome和NodeJS使用的引擎。它是用C++(一種底層語言)編寫的。但是如果每個人都創造一個引擎,那場面就不是可控范圍內的了。
因此,為了給這些引擎確立一個規范,ECMA的標準誕生了,該標準主要提供如何編寫引擎和JavaScript所有功能的規范。這就是新功能能在ECMAScript 6、7、8上實現的原因。同時,引擎也進行了更新以支持這些新功能。于是,我們便可以在開發過程中檢查了瀏覽器中JS高級功能的可用性。
我們輸入的代碼將通過以下階段
1.Parser
2.AST
3.Interpreter生成ByteCode
4.Profiler
5.Compiler生成優化后的代碼
別被上面的流程給唬住了,在幾分鐘后您將了解它們是協同運作的。
在進一步深入這些階段之前,您需要先了解Interpreter和Compiler的區別。
Interpreter VS Compiler
通常,將代碼轉換成機器可讀語言的方法有兩種。我們將要討論的概念不僅適用于JavaScript,而且適用于大多數編程語言,例如Python,Java等。
·Interpreter逐行讀取代碼并立即執行。
·Compiler讀取您的整個代碼,進行一些優化,然后生成優化后的代碼。
當您閱讀完上面的推薦文章后,您可能已經了解到Babel實際上是一個JS Compiler,它可以接收您編寫的新版本JS代碼并向下編譯為與瀏覽器兼容的JS代碼(舊版本的JS代碼)。
Interpreter和Compiler的優缺點
·Interpreter的優點是無需等待編譯即可立即執行代碼。這對在瀏覽器中運行JS提供了極大的便利,因為所有用戶都不想浪費時間在等待代碼編譯這件事上。但是,當有大量的JS代碼需要執行時會運行地比較慢。還記得上面例子中的那一小段代碼嗎?代碼中執行了1000次函數調用。函數add被調用了1000次,但他的輸出保持不變。但是Interpreter還是逐行執行,會顯得比較慢。
·在同樣的情況下,Compiler可以通過用2代替循環(因為add函數每次都是執行1+1)來進行一些優化。Compiler最終給出的優化代碼可以在更短的時間內執行完成。
綜上所述,Interpreter可以立即開始執行代碼,但不會進行優化。Compiler雖然需要花費一些時間來編譯代碼,但是會生成對執行時更優的代碼。
好的,Interpreter和Compiler必要知識我們已經了解了?,F在讓我們回到主題——JS引擎。
因此,考慮到編譯器和解釋器的優缺點,如果我們同時利用兩者的優點,該怎么辦?這就是JIT(Just In Time)Compiler的用武之地。它是Interpreter和Compiler的結合,現在大多數瀏覽器都在更快,更高效地實現此功能。同時V8引擎也使用此功能。
1.Parser是一種通過各種JavaScript關鍵字來識別,分析和分類程序各個部分的解析器。它可以區分代碼是一個方法還是一個變量。
2.然后,AST(抽象語法樹)基于Parser的分類構造樹狀結構。您可以使用AST Explorer查看該樹的結構。
3.隨后將AST提供給Interpreter生成ByteCode。如上文所述,ByteCode不是最底層的代碼,但可以被執行。在此階段,瀏覽器借助V8引擎執行ByteCode進行,因此用戶無需等待。
4.同時,Profiler將查找可以被優化的代碼,然后將它們傳遞給Compiler。Compiler生成優化代碼的同時,瀏覽器暫時用ByteCode執行操作。并且,一旦Compiler生成了優化代碼,優化代碼則將完全替換掉臨時的ByteCode。
5.通過這種方式,我們可以充分利用Interpreter和Compiler的優點。Interpreter執行代碼的同時,Profiler尋找可以被優化的代碼,Compiler則創建優化的代碼。然后,將ByteCode碼替換為優化后的較為底層的代碼,例如機器代碼。
這僅意味著性能將在逐漸提高,同時不會有阻塞執行的時間。
關于ByteCode
作為機器代碼,ByteCode不能被所有計算機理解及執行。它仍然需要像虛擬機或像Javascript V8引擎這樣的中間件才能將其轉換為機器可讀的語言。這就是為什么我們的瀏覽器可以在上述5個階段中借助JavaScript引擎在Interpreter中執行ByteCode的原因。
JavaScript是一門解釋型語言嗎?
JavaScript是但不完全是一門解釋型語言。Brendan Eich最初是在JavaScript的早期階段創建JavaScript引擎“SpiderMonkey”的。該引擎有一個Interpreter來告訴瀏覽器該怎么執行代碼。但是現在我們的引擎不僅包括了Interpreter,還有Compiler。我們的代碼不僅可以被轉換成ByteCode,還可以被編譯輸出優化后的代碼。因此,從技術上講,這完全取決于引擎是如何實現的。
以上我們簡短的介紹了一下JavaScript引擎的整體原理,也是十分簡單易懂的,雖然可能對這個項目并不是十分了解的情況下也能寫出代碼,但是如果了解了一些幕后知識,寫出的代碼將更為優秀。