原文連接:JavaScript: Under the Hoodjavascript
最初,JavaScript 只能在 Web 瀏覽器中運行,可是隨着 Node 的出現,如今 JavaScript 也能夠在服務端運行。雖然咱們可能知道應該在什麼時候何地去使用它, 可是咱們真的瞭解這些腳本執行的背後發生了什麼嗎?java
若是您以爲本身對 JavaScript 引擎有了一些瞭解的話,能夠先給本身鼓個掌,但不要急着關掉本文,我相信閱讀完成後您仍然能夠從中學到一些東西。編程
JavaScript 是一門高級語言,可是最終計算機能理解只有1和0。 那麼咱們編寫的代碼是如何被計算機理解的呢? 掌握所學編程語言的基礎知識將讓您能編寫出更好的代碼。 在本文中,咱們僅探討一個問題:JavaScript 是如何工做的?瀏覽器
下面讓咱們進入正題~bash
這是本文將要探索的主要內容,它負責使計算機理解咱們編寫的 JS 代碼。JavaScript 引擎是一種用於將咱們的代碼轉換爲機器可讀語言的引擎。若是沒有 JavaScript 引擎,您編寫的代碼對計算機來講簡直是一堆「胡言亂語」。不只僅是 JavaScript ,其餘全部編程語言都須要一個相似的引擎,來將這些「胡言亂語」轉換成對計算機有意義的語言。babel
目前有多種 JavaScript 引擎在可供使用。您能夠在 Wikipedia 上查閱全部可用的 JavaScript 引擎。它們也被稱爲 ECMAScript 引擎,這樣叫的具體緣由會在下文中說起。 下面是一些咱們平常可能會用到的 JavaScript 引擎:編程語言
除此以外的其它引擎,能夠自行搜索瞭解。接下來,咱們將深刻研究這些引擎,以瞭解它們是如何翻譯 JavaScript 文件的。ide
咱們已經知道了引擎是必須的,由此可能不由會想:函數
是誰發明了 JavaScript 引擎?工具
答案是,任何人均可以。它只是分析咱們的代碼並將其翻譯的另外一種語言的工具。V8 是最受歡迎的 JavaScript 引擎之一,也是 Chrome 和 NodeJS 使用的引擎。它是用 C++(一種底層語言)編寫的。可是若是每一個人都創造一個引擎,那場面就不是可控範圍內的了。
所以,爲了給這些引擎確立一個規範,ECMA 的標準誕生了,該標準主要提供如何編寫引擎和 JavaScript 全部功能的規範。這就是新功能能在 ECMAScript 六、七、8 上實現的緣由。同時,引擎也進行了更新以支持這些新功能。 因而,咱們即可以在開發過程當中檢查了瀏覽器中 JS 高級功能的可用性。
下面咱們對 V8 引擎進行進一步的探索,由於基本概念在全部引擎中是一致的。
上圖就是 JS Engine 內部的工做流程。咱們輸入的代碼將經過如下階段,
別被上面的流程給唬住了,在幾分鐘後您將瞭解它們是協同運做的。
在進一步深刻這些階段以前,您須要先了解 Interpreter 和 Compiler 的區別。
一般,將代碼轉換成機器可讀語言的方法有兩種。 咱們將要討論的概念不只適用於 JavaScript ,並且適用於大多數編程語言,例如 Python,Java 等。
讓咱們來看下面這個例子。
function add(a, b) {
return a+b
}
for(let i = 0; i < 1000; i++) {
add(1 + 1)
}
複製代碼
上面的示例循環調用了 add
函數1000次,該函數將兩個數字相加並返回總和。
從上圖中能夠看出,ByteCode 只是中間碼,計算機仍須要對其進行翻譯才能執行。 可是 Interpreter 和 Compiler 都將源代碼轉換爲機器語言,它們惟一的區別在於轉換的過程不盡相同。
若是你想了解更多它們以前的區別,推薦閱讀這篇文章。
當您閱讀完上面的推薦文章後,您可能已經瞭解到 Babel 其實是一個 JS Compiler ,它能夠接收您編寫的新版本 JS 代碼並向下編譯爲與瀏覽器兼容的 JS 代碼(舊版本的 JS 代碼)。
綜上所述,Interpreter 能夠當即開始執行代碼,但不會進行優化。 Compiler 雖然須要花費一些時間來編譯代碼,可是會生成對執行時更優的代碼。
好的,Interpreter 和 Compiler 必要知識咱們已經瞭解了。如今讓咱們回到主題——JS 引擎。
所以,考慮到編譯器和解釋器的優缺點,若是咱們同時利用二者的優勢,該怎麼辦? 這就是 JIT(Just In Time) Compiler 的用武之地。它是 Interpreter 和 Compiler 的結合,如今大多數瀏覽器都在更快,更高效地實現此功能。同時 V8 引擎也使用此功能。
在這個過程當中,
這僅意味着性能將在逐漸提升,同時不會有阻塞執行的時間。
做爲機器代碼,ByteCode 不能被全部計算機理解及執行。它仍然須要像虛擬機或像 Javascript V8 引擎這樣的中間件才能將其轉換爲機器可讀的語言。 這就是爲何咱們的瀏覽器能夠在上述5個階段中藉助 JavaScript 引擎在 Interpreter 中執行 ByteCode 的緣由。
因此您能夠會有另外一個問題,
JavaScript 是但不徹底是一門解釋型語言。Brendan Eich 最初是在 JavaScript 的早期階段建立 JavaScript 引擎 「 SpiderMonkey」 的。該引擎有一個 Interpreter 來告訴瀏覽器該怎麼執行代碼。 可是如今咱們的引擎不只包括了 Interpreter,還有 Compiler。 咱們的代碼不只能夠被轉換成 ByteCode,還能夠被編譯輸出優化後的代碼。 所以,從技術上講,這徹底取決於引擎是如何實現的。
JavaScript 引擎的總體工做原理就是這樣。相信您無需學習 JavaScript 也能夠理解。 固然,您甚至能夠在不知道 JavaScript 如何工做的狀況下編寫代碼。 可是,若是咱們瞭解一些幕後的知識,或許能讓咱們編寫出更好的代碼。
歡迎轉載,記得註明做者和來源哦~~