首頁  >  文章  >  web前端  >  javascript依賴什麼支持

javascript依賴什麼支持

青灯夜游
青灯夜游原創
2022-09-30 15:19:332269瀏覽

javascript依賴底層javascript引擎的支援。 javascript運行在瀏覽器,主要依靠瀏覽器的js引擎解釋執行js程式碼;JavaScript引擎是一個專門處理JavaScript腳本的虛擬機,一般會附帶在網頁瀏覽器之中,用於解釋和執行js腳本。

javascript依賴什麼支持

本教學操作環境:windows7系統、javascript1.8.5版、Dell G3電腦。

javascript依賴底層js引擎的支援。

javascript運行在瀏覽器,主要依賴瀏覽器的js引擎來解釋執行js程式碼。其他有js引擎的軟體也可以運作js,但一般js和網頁關係較大,所以一般在瀏覽器當中運作。

javascript引擎

JavaScript引擎是一個專門處理JavaScript腳本的虛擬機,一般會附帶在網頁瀏覽器之中,用於解釋和執行js腳本。

著名的js引擎:

    Mozilla:SpiderMonkey引擎,世界第一款JavaScript引擎,有C/C 編寫,用於Mozilla Firefox 1.0~3.0版本

    Google:V8引擎,由C /彙編語言編寫,用於chrome瀏覽器

    微軟:Chakra(查克拉,笑)引擎,用於Internet Explorer 9的32位元版本

瀏覽器核心與JS引擎的關係

以webkit為例:

javascript依賴什麼支持

## V8引擎

1、V8引擎的原理

V8引擎是用C 寫的Google開源高效能的JavaScript和WebAssembly引擎,用於Chrome和Node.js等。

它能夠實現ECMAScript和WebAssembly,並在Windows7或更高版本,macOS 10.12 和使用x64,IA-32,ARM或MIPS處理器的Linux系統上運行。

V8引擎可以獨立運行,也可以嵌入到任何C 應用程式中運行。例如,可以將V8引擎中使用Node.js看做是將V8引擎嵌入到了應用程式中,那麼Node.js就具備了執行JavaScript程式碼的能力。

原理圖:

javascript依賴什麼支持

①、Parse模組會將JavaScript程式碼轉換成AST,這是因為解譯器並不會直接認識JavaScript程式碼。如果函數沒有被調用,是不會被轉換成AST的

②、Ignition是解釋器,會將AST轉換為ByteCode。同時會收集TurboFan優化所需的資訊(例如函數參數的類型信息,有了類型才能真實的運算)。如果函數只呼叫一次,Ignition將AST轉換為ByteCode

③、為什麼最後轉換為字節碼,而不是直接轉換成機器碼?

因為JS程式碼在什麼樣的環境下執行並不固定,有可能是使用Windows環境、或是mac環境、或是Linux環境的瀏覽器上,也可能是在Node.js中,環境不固定,不同環境會有不同的CPU,不同的CPU擁有不同的CPU架構,不同的架構能夠執行的機器指令是不一樣的。

javascript依賴什麼支持

轉換為V8引擎規定好的字節碼,不管在什麼環境下都可以執行,是跨平台的,最後V8引擎會把字節碼轉換彙編指令,再轉換為不同環境對應的CPU指令。

但每次都走這套流程,還是不夠方便。例如有一個函數是重複使用的,但使用前面一套流程,每次使用這個函數的時候,都需要轉換成字節碼,然後再變成CPU指令,效能比較低,如果可以直接將這個函數變成機器指令保存下來,使用這個函數的時候,直接運行機器指令,性能比較高,但是如果這個函數只運行一次,就沒有必要轉換變成機器碼保存下來,會浪費空間。

④、使用TurboFan函式庫,是一個編譯器,會將字節碼編譯為CPU可以直接執行的機器碼,他可以利用ignition來收集函數的執行信息,了解到哪些函數執行次數比較多,會將這類函數標記為hot ,熱函數,然後就會將這個函數轉換為優化之後的機器指令,以後再使用這個熱函數的時候,不需要上面繁瑣的過程,直接執行機器指令就行。

但是實際上機器碼也會被還原為ByteCode,這是因為如果後續執行函數的過程中,類型發生改變,之前優化的機器碼並不能正確地處理運算,就會逆向的轉換為字節碼。

⑤、Deoptimization: 例如有一個函數

function  sum(num1,num2){
   num1+num2
}

呼叫sum函數

sum(20,30)
sum(28,30)

如果传入数字,调用sum函数,需要做的工作就是对两个数字进行相加,执行的机器指令永远是对这两个数字进行相加.
一旦改变传入值的类型,如果变成字符串,那么这个函数的意思就是两个字符串拼接。

sum("aaa","bbb")

这两种类型的传入值执行“+”操作对应的机器指令是不同的,JavaScript是不会对传入值的类型做检测的,那么还是使用数字相加的机器指令,这次函数调用的结果是不能够使用的。

但是V8引擎中提供了一种解决办法Deoptimization过程,这个过程是,一旦发现在执行机器指令时候,执行的操作不一样的时候,Deoptimization会反向优化,又转化为字节码,执行后续操作。

2、V8引擎的解析图

javascript依賴什麼支持

V8执行的细节:

①、Blink将源码交给V8引擎,Stream获取到源码并且进行编码转换

②、scanner会进行词法分析,词法分析之后会将代码转换为成tokens

③、tokens会被转换为AST树,经过Parser和PreParser:

Parser就是直接将tokens转换为AST树架构;

PreParser预解析,为什么会需要预解析?

1)如上图中的函数outer(),内部有一个函数inner(),但是并没有任何调用inner()的代码,那么就意味着并不是所有的JavaScript代码,都是一开始就被执行。对所有的JavaScript代码进行解析,必定会影响网页的运行效率。

2)V8引擎实现了Lazy Parsing(延迟解析)的方案,作用是将不必要的函数进行预解析,我只需要知道有这么个函数就行,也就是只解析暂时需要的内容,对函数的全量解析在函数被调用的时候才会执行。

3)例如上图中函数outer中的inner函数,它就是会执行预解析。

④、生成AST树之后,会被Ignition转成字节码,之后的过程就是代码的执行过程。

【相关推荐:javascript视频教程编程视频

以上是javascript依賴什麼支持的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn