「動畫演示」JavaScript引擎運行原理

JavaScript 很酷,但是 JS 引擎是如何才能理解我們編寫的代碼呢?作為 JS 開發(fā)人員铣墨,我們通常不需要自己處理編譯器室埋。然而,了解 JS 引擎的基礎(chǔ)知識并了解它如何處理JS代碼伊约,并將其轉(zhuǎn)換成機器能夠理解的東西姚淆,絕對是個有益無害的事情。

注意:本文主要基于 Node.js 和基于 Chrome 的瀏覽器使用的 V8 引擎屡律。

HTML解析器遇到帶有源代碼的script標簽腌逢。來自此源的代碼從網(wǎng)絡(luò),緩存或已安裝的服務(wù)工作程序中加載超埋。響應(yīng)是將請求的腳本作為字節(jié)流搏讶,由字節(jié)流解碼器負責(zé)。字節(jié)流解碼器在下載字節(jié)流時對其進行解碼霍殴。

字節(jié)流解碼器從已解碼的字節(jié)流中創(chuàng)建令牌媒惕。例如,0066解碼為f, 0075到u,006e到n, 0063到c, 0074到t, 0069到i, 006f到o, 006e到n来庭,后面跟一個空格妒蔚。就像JS中的function,這是 JS 中的一個保留關(guān)鍵字,它會創(chuàng)建一個標記肴盏,并將其發(fā)送給解析器科盛。對于字節(jié)流的其余部分也是如此。

該引擎使用兩個解析器:預(yù)解析器(pre-parser)和解析器(parser)菜皂。預(yù)解析器只提前檢查標記贞绵,以查看是否有語法錯誤。這可以減少發(fā)現(xiàn)代碼中的錯誤所需的時間恍飘,否則解析器稍后就會發(fā)現(xiàn)這些錯誤榨崩。

如果沒有錯誤,解析器將根據(jù)從字節(jié)流解碼器接收到的標記創(chuàng)建節(jié)點常侣。使用這些節(jié)點蜡饵,它創(chuàng)建了一個抽象語法樹,即AST胳施。

接下來溯祸,輪到解釋器(interpreter)了。遍歷AST并根據(jù)AST包含的信息生成字節(jié)碼的解釋器舞肆。一旦字節(jié)碼完全生成焦辅,AST就會被刪除,從而清除內(nèi)存空間椿胯。最后筷登,生成的機器碼就可以在電腦上運行了。

雖然字節(jié)碼很快哩盲,但它可以更快前方。當這個字節(jié)碼運行時,將生成信息廉油。它可以檢測某些行為是否經(jīng)常發(fā)生惠险,以及所使用數(shù)據(jù)的類型。也許已經(jīng)調(diào)用一個函數(shù)幾十次了:現(xiàn)在是時候優(yōu)化它了抒线,這樣它會運行得更快!

字節(jié)碼與生成的類型反饋一起發(fā)送到優(yōu)化編譯器(ptimizing compiler)班巩。優(yōu)化的編譯器接收字節(jié)碼和類型反饋,并根據(jù)這些信息生成高度優(yōu)化的機器碼嘶炭。

JS 是一種動態(tài)類型語言抱慌,這意味著數(shù)據(jù)類型可以不斷變化。如果 JS引擎每次都要檢查某個值的數(shù)據(jù)類型眨猎,那么速度會非常慢抑进。

相反,JS 引擎使用一種稱為內(nèi)聯(lián)緩存(inline caching)的技術(shù)睡陪。它將代碼緩存在內(nèi)存中寺渗,希望將來它會以相同的行為返回相同的值.假設(shè)某個函數(shù)被調(diào)用100次夕凝,并且到目前為止總是返回相同的值。它將假設(shè)在第101次調(diào)用它時也會返回這個值户秤。

假設(shè)我們有以下函數(shù)sum,(到目前為止)每次都使用數(shù)值作為參數(shù)來調(diào)用它:

ffunction sum(a, b){

? return a + b

}

sum(1, 2)

執(zhí)行結(jié)果為 3逮矛。下次調(diào)用它時鸡号,它將假定我們再次使用兩個相同數(shù)字對其進行調(diào)用。

那么就不需要動態(tài)查找须鼎,只需要使用存儲在特定內(nèi)存槽中的結(jié)果鲸伴,該槽已經(jīng)有一個引用。否則晋控,如果假設(shè)不正確汞窗,它將反優(yōu)化代碼并恢復(fù)到原始字節(jié)碼,而不是優(yōu)化后的機器碼赡译。

例如仲吏,下一次調(diào)用它時,我們傳遞的是字符串而不是數(shù)字蝌焚。因為 JS 是動態(tài)類型的裹唆,所以這樣做不會有任何錯誤。

function sum(a, b){

? return a + b

}

sum('1', 2)

這意味著數(shù)字2將被強制轉(zhuǎn)換成字符串只洒,而函數(shù)將返回字符串'12'许帐。它返回執(zhí)行解釋的字節(jié)碼并更新類型反饋。

我希望這篇文章對你有用!當然毕谴,在這篇文章中還沒有涉及到引擎的更多部分(JS堆成畦,調(diào)用堆棧,等等)涝开,后續(xù)會繼續(xù)分享循帐。如果你對 JS 的內(nèi)部機制感興趣,強烈建議自己可以做一些研究忠寻,V8 是開源的惧浴,并且有一些很棒的文檔說明它是如何工作的。

https://dev.to/lydiahallie/javascript-visualized-the-javascript-engine-4cdf

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末奕剃,一起剝皮案震驚了整個濱河市衷旅,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌纵朋,老刑警劉巖柿顶,帶你破解...
    沈念sama閱讀 216,692評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異操软,居然都是意外死亡嘁锯,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,482評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來家乘,“玉大人蝗羊,你說我怎么就攤上這事∪示猓” “怎么了耀找?”我有些...
    開封第一講書人閱讀 162,995評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長业崖。 經(jīng)常有香客問我野芒,道長,這世上最難降的妖魔是什么双炕? 我笑而不...
    開封第一講書人閱讀 58,223評論 1 292
  • 正文 為了忘掉前任狞悲,我火速辦了婚禮,結(jié)果婚禮上妇斤,老公的妹妹穿的比我還像新娘摇锋。我一直安慰自己,他們只是感情好站超,可當我...
    茶點故事閱讀 67,245評論 6 388
  • 文/花漫 我一把揭開白布乱投。 她就那樣靜靜地躺著,像睡著了一般顷编。 火紅的嫁衣襯著肌膚如雪戚炫。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,208評論 1 299
  • 那天媳纬,我揣著相機與錄音双肤,去河邊找鬼。 笑死钮惠,一個胖子當著我的面吹牛茅糜,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播素挽,決...
    沈念sama閱讀 40,091評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼蔑赘,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了预明?” 一聲冷哼從身側(cè)響起缩赛,我...
    開封第一講書人閱讀 38,929評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎撰糠,沒想到半個月后酥馍,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,346評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡阅酪,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,570評論 2 333
  • 正文 我和宋清朗相戀三年旨袒,在試婚紗的時候發(fā)現(xiàn)自己被綠了汁针。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,739評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡砚尽,死狀恐怖施无,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情必孤,我是刑警寧澤帆精,帶...
    沈念sama閱讀 35,437評論 5 344
  • 正文 年R本政府宣布,位于F島的核電站隧魄,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏隘蝎。R本人自食惡果不足惜购啄,卻給世界環(huán)境...
    茶點故事閱讀 41,037評論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望嘱么。 院中可真熱鬧狮含,春花似錦、人聲如沸曼振。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,677評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽冰评。三九已至映胁,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間甲雅,已是汗流浹背解孙。 一陣腳步聲響...
    開封第一講書人閱讀 32,833評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留抛人,地道東北人弛姜。 一個月前我還...
    沈念sama閱讀 47,760評論 2 369
  • 正文 我出身青樓,卻偏偏與公主長得像妖枚,于是被迫代替她去往敵國和親廷臼。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,647評論 2 354