JavaScript目前能夠在node環境和瀏覽器中執行, 咱們編寫的JavaScript代碼是如何被計算機理解的?
JavaScript 是一門高級語言,可是最終計算機能理解只有1和0。那麼咱們編寫的代碼是如何被計算機理解的呢?掌握所學編程語言的基礎知識將讓您能編寫出更好的代碼。javascript
分析咱們的代碼並將其翻譯的另外一種語言的工具。java
JavaScript引擎的主要工做就是解析咱們的js代碼,使計算機能夠理解咱們編寫的代碼。JavaScript 引擎是一種用於將咱們的代碼轉換爲機器可讀語言的引擎。不單單是 JavaScript ,其餘全部編程語言都須要一個相似的引擎,來將這些「胡言亂語」轉換成對計算機有意義的語言。
目前常見的JavaScript引擎:
Chrome: blink(V8)
IE: Trident
firefox: Gecko
Safari: webkit
Opera: blinknode
V8 是最受歡迎的 JavaScript 引擎之一,也是 Chrome 和 NodeJS 使用的引擎。它是用 C++(一種底層語言)編寫的。任何人均可以寫一個js引擎去處理js, 若是這些引擎沒有一個統一的規範,每一個人都創造一個引擎,那場面就不可收拾了。所以ECMA 的標準誕生了,該標準主要提供如何編寫引擎和 JavaScript 全部功能的規範。web
引擎解析javascript代碼的大體流程編程
上圖就是 JS Engine 內部的工做流程。咱們輸入的代碼將經過如下階段:瀏覽器
一般,將代碼轉換成機器可讀語言的方法有兩種。Interpreter和Compiler編程語言
function num(a,b){
return a+b;
}
for(let i = 0; i < 999; i++){
num(1+1);
}
複製代碼
當引擎開始執行這段代碼時,Interpreter首先開始工做。 Interpreter解析這段代碼並當即將代碼翻譯成機器碼,而且當即輸出結果,它的工做僅僅是實時地將代碼轉換爲咱們的計算機能夠理解的內容並執行。 Compiler解析這段代碼時,發現for循環中在循環調用 num(1+1)並一直返回固定的結果, Compiler在將此代碼轉化成機器碼時對此代碼優化。ide
Interpreter 和 Compiler 都將源代碼轉換爲機器語言,它們惟一的區別在於轉換的過程不盡相同。函數
Interpreter 的優勢是無需等待編譯便可當即執行代碼。這對在瀏覽器中運行 JS 提供了極大的便利,由於全部用戶都不想浪費時間在等待代碼編譯這件事上。可是,當有大量的 JS 代碼須要執行時會運行地比較慢。還記得上面例子中的那一小段代碼嗎?代碼中執行了1000次函數調用。函數 num 被調用了1000次,但他的輸出保持不變。可是 Interpreter 仍是逐行執行,會顯得比較慢。工具
在一樣的狀況下,Compiler 能夠經過用2代替循環(由於 num 函數每次都是執行1 + 1)來進行一些優化。Compiler 最終給出的優化代碼能夠在更短的時間內執行完成。
綜上所述,Interpreter 能夠當即開始執行代碼,但不會進行優化。Compiler 雖然須要花費一些時間來編譯代碼,可是會生成對執行時更優的代碼。
Profiler 將查找能夠被優化的代碼,而後將它們傳遞給 Compiler。Compiler 生成優化代碼的同時,瀏覽器暫時用 ByteCode 執行操做。而且,一旦 Compiler 生成了優化代碼,優化代碼則將徹底替換掉臨時的 ByteCode。
經過這種方式,咱們能夠充分利用 Interpreter 和 Compiler 的優勢。Interpreter 執行代碼的同時,Profiler 尋找能夠被優化的代碼,Compiler 則建立優化的代碼。而後,將 ByteCode 碼替換爲優化後的較爲底層的代碼,例如機器代碼。
js是一個解釋型和編譯型並存的語言, 這也是js在V8下很快的緣由之一。 當即執行代碼會被解釋器立馬執行, 同時Profiler會對代碼進行優化,再將優化後的代碼交給編譯器Compiler進行代碼轉化。