成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

JavaScript 語法解析、AST、V8、JIT

hedge_hog / 3521人閱讀

摘要:語法解析是如何執(zhí)行的原文地址,對于常見編譯型語言例如來說,編譯步驟分為詞法分析語法分析語義檢查代碼優(yōu)化和字節(jié)碼生成。對于解釋型語言例如來說,通過詞法分析語法分析語法樹,就可以開始解釋執(zhí)行了。

JavaScript 語法解析、AST、V8、JIT JavaScript 是如何執(zhí)行的

原文地址,對于常見編譯型語言(例如:Java)來說,編譯步驟分為:詞法分析->語法分析->語義檢查->代碼優(yōu)化和字節(jié)碼生成。

對于解釋型語言(例如 JavaScript)來說,通過詞法分析 -> 語法分析 -> 語法樹,就可以開始解釋執(zhí)行了。

具體過程是這樣的:

1.詞法分析是將字符流(char stream)轉(zhuǎn)換為記號流(token stream)

NAME "AST"  
EQUALS  
NAME "is Tree"  
SEMICOLON 

2.語法分析成 AST (Abstract Syntax Tree),你可以在這里試試 http://esprima.org/

3.預(yù)編譯,當(dāng)JavaScript引擎解析腳本時,它會在預(yù)編譯期對所有聲明的變量和函數(shù)進(jìn)行處理!并且是先預(yù)聲明變量,再預(yù)定義函數(shù)!

4.解釋執(zhí)行,在執(zhí)行過程中,JavaScript 引擎是嚴(yán)格按著作用域機(jī)制(scope)來執(zhí)行的,并且 JavaScript 的變量和函數(shù)作用域是在定義時決定的,而不是執(zhí)行時決定的。JavaScript 中的變量作用域在函數(shù)體內(nèi)有效,無塊作用域;

function func(){
    for(var i = 0; i < array.length; i++){  
      //do something here.  
    }
    //此時 i 仍然有值,及 i == array.length  
    console.log(i); // 但在 java 語言中,則無效
}

JavaScript 引擎通過作用域鏈(scope chain)把多個嵌套的作用域串連在一起,并借助這個鏈條幫助 JavaScript 解釋器檢索變量的值。這個作用域鏈相當(dāng)于一個索引表,并通過編號來存儲它們的嵌套關(guān)系。當(dāng) JavaScript 解釋器檢索變量的值,會按著這個索引編號進(jìn)行快速查找,直到找到全局對象(global object)為止,如果沒有找到值,則傳遞一個特殊的 undefined 值。

var scope = "global";
scopeTest();
function scopeTest(){  
    console.log(scope);  
    var scope = "local";  
    console.log(scope); 
}
打印結(jié)果:undefined,local;
V8、JIT

我們常說的 V8 是 Google 發(fā)布的開源 JavaScript 引擎,采用 C++ 編寫。SpiderMonkey(Mozilla,基于 C)、Rhino(Mozilla,基于 Java),而 Nodejs 依賴于 V8 引擎開發(fā),接下來的內(nèi)容是 JavaScript 在 V8 引擎中的運(yùn)行狀態(tài),而類似的 JavaScript 現(xiàn)代引擎對于這些實(shí)現(xiàn)大同小異。

在本文的開頭提到了編譯型語言,解釋型語言。JavaScript 是解釋型語言且弱類型,在生成 AST 之后,就開始一邊解釋,一邊執(zhí)行,但是有個弊端,當(dāng)某段代碼被多次執(zhí)行時,它就有了可優(yōu)化的空間(比如類型判斷優(yōu)化),而不用一次次的去重復(fù)之前的解釋執(zhí)行。
編譯型語言如 JAVA,可以在執(zhí)行前就進(jìn)行優(yōu)化編譯,但是這會耗費(fèi)大量的時間,顯然不適用于 Web 交互。

于是就有了,JIT(Just-in-time),JIT 是兩種模式的混合。

它是如何工作的呢:

1.在 JavaScript 引擎中增加一個監(jiān)視器(也叫分析器)。監(jiān)視器監(jiān)控著代碼的運(yùn)行情況,記錄代碼一共運(yùn)行了多少次、如何運(yùn)行的等信息,如果同一行代碼運(yùn)行了幾次,這個代碼段就被標(biāo)記成了 “warm”,如果運(yùn)行了很多次,則被標(biāo)記成 “hot”。

2.(基線編譯器)如果一段代碼變成了 “warm”,那么 JIT 就把它送到基線編譯器去編譯,并且把編譯結(jié)果存儲起來。比如,監(jiān)視器監(jiān)視到了,某行、某個變量執(zhí)行同樣的代碼、使用了同樣的變量類型,那么就會把編譯后的版本,替換這一行代碼的執(zhí)行,并且存儲。

3.(優(yōu)化編譯器)如果一個代碼段變得 “hot”,監(jiān)視器會把它發(fā)送到優(yōu)化編譯器中。生成一個更快速和高效的代碼版本出來,并且存儲。例如:循環(huán)加一個對象屬性時,假設(shè)它是 INT 類型,優(yōu)先做 INT 類型的判斷

4.(去優(yōu)化)可是對于 JavaScript 從來就沒有確定這么一說,前 99 個對象屬性保持著 INT 類型,可能第 100 個就沒有這個屬性了,那么這時候 JIT 會認(rèn)為做了一個錯誤的假設(shè),并且把優(yōu)化代碼丟掉,執(zhí)行過程將會回到解釋器或者基線編譯器,這一過程叫做去優(yōu)化。

優(yōu)化代碼圖例:

“hot” 代碼

優(yōu)化前

優(yōu)化后

總結(jié)

明白一些基本原理能拓展出更多的東西,比如:

1.var a = 10; var b = 20; ==> var a=10, b=20; 這些改代碼的好處是什么,如何從原理解釋?

2.JavaScript 的函數(shù)和變量是在什么時候聲明的,函數(shù)聲明和函數(shù)表達(dá)式的區(qū)別?

3.如何通過編譯器的優(yōu)化原理,如何提高 JavaScript 的執(zhí)行效率?

閱讀原文

作者:肖沐宸,github。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/89521.html

相關(guān)文章

  • 【1】解析與編譯

    摘要:解析與編譯從源程序到可以被計算機(jī)識別的目標(biāo)程序主要包含兩個階段解析生成抽象語法樹編譯執(zhí)行解析以引擎為例,前置的解析被分為兩種類型。解釋器就像口譯員,從源代碼第一行開始進(jìn)行解析編譯執(zhí)行。 解析與編譯 Javascript 從源程序到可以被計算機(jī)識別的目標(biāo)程序主要包含兩個階段: 解析生成抽象語法樹 編譯執(zhí)行 解析 以V8引擎為例,前置的解析被分為兩種類型:Pre-Parser、Full...

    Meathill 評論0 收藏0
  • V8 Ignition:JS 引擎與字節(jié)碼的不解之緣(轉(zhuǎn)載)

    摘要:縱覽各個引擎的實(shí)現(xiàn),我們發(fā)現(xiàn)基于字節(jié)碼的實(shí)現(xiàn)是主流。引入字節(jié)碼之后,的性能得到了顯著的提升。而這次引入字節(jié)碼卻是向著相反的方向后退。這便是引入字節(jié)碼的主要動機(jī)。如今也回到了字節(jié)碼的懷抱,不禁令人感嘆引擎與字節(jié)碼真是有著不解之緣 首先貼個Javascript性能測試站點(diǎn),測試并展示了數(shù)個 JavaScript 引擎的性能數(shù)據(jù):arewefastyetshowImg(https://seg...

    lijinke666 評論0 收藏0
  • 「譯」JavaScript 究竟是如何工作的?(第一部分)

    摘要:文章的第二部分涵蓋了內(nèi)存管理的概念,不久后將發(fā)布。的標(biāo)準(zhǔn)化工作是由國際組織負(fù)責(zé)的,相關(guān)規(guī)范被稱為或者。隨著分析器和編譯器不斷地更改字節(jié)碼,的執(zhí)行性能逐漸提高。 原文地址:How Does JavaScript Really Work? (Part 1) 原文作者:Priyesh Patel 譯者:Chor showImg(https://segmentfault.com/img...

    Youngdze 評論0 收藏0
  • JavaScript到底是解釋型語言還是編譯型語言?

    摘要:編譯型語言解釋型語言主要問題是沒有團(tuán)體或者組織規(guī)定這些例如編譯型語言和解釋型語言的定義以及如何劃分。下面是處理聲明語句的過程一旦引擎進(jìn)入一個執(zhí)行具體代碼的執(zhí)行上下文函數(shù),它就對代碼進(jìn)行詞法分析或者分詞。這是解釋型語言需要的。 幾天前一個剛接觸 JavaScript 的朋友問我 JavaScript 是編譯型語言還是解釋型語言。從一個初學(xué)者那里聽到這樣的問題讓我有些驚訝,因為所有初學(xué)者都...

    gghyoo 評論0 收藏0
  • javascript引擎——V8

    摘要:類將源代碼解釋并構(gòu)建成抽象語法樹,使用類來創(chuàng)建它們,并使用類來分配內(nèi)存。類抽象語法樹的訪問者類,主要用來遍歷抽象語法樹。在該函數(shù)中,先使用類來生成抽象語法樹再使用類來生成本地代碼。 通過上一篇文章,我們知道了JavaScript引擎是執(zhí)行JavaScript代碼的程序或解釋器,了解了JavaScript引擎的基本工作原理。我們經(jīng)常聽說的JavaScript引擎就是V8引擎,這篇文章我們...

    luoyibu 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<