91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

JavaScript內部原理是怎樣的

發布時間:2021-09-30 17:38:19 來源:億速云 閱讀:126 作者:柒染 欄目:web開發

本篇文章給大家分享的是有關JavaScript內部原理是怎樣的,小編覺得挺實用的,因此分享給大家學習,希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。

簡介

Javascript  是一種奇怪語言,有些人喜歡它,有些人討厭它。它有許多獨特的機制,這些機制在其他流行語言中不存在,也沒有對應的機制,還有突出明顯的就是代碼的執行順序。

了解瀏覽器環境,它的組成以及它的工作原理會讓我們在編寫 JS 時更加自信,并為可能發生的潛在問題做好了充分的準備。

JavaScript引擎

最流行的JavaScript引擎是V8,它是用c++編寫的,并被基于Chrome的瀏覽器使用,如Chrome、Opera甚至Edge。基本上,這個引擎是一個將  JS 轉換成機器碼并在計算機的中央處理器(CPU)上執行結果的程序。

編譯

當瀏覽器加載 JS  文件時,V8的解析器將其轉換為一個抽象語法樹(AST)。該樹用于生成字節碼的解釋器。字節碼是一種可以通過編譯成非優化的機器碼來執行的機器碼的抽象。V8在主線程中執行它,而優化編譯器TurboFan在另一個線程中進行一些優化并生成優化的機器碼。

這個管道稱為即時(JIT)編譯。

JavaScript內部原理是怎樣的

調用堆棧

JavaScript  是一種單線程編程語言,只有一個調用堆棧。它意味著我們的代碼是同步執行的。每當一個函數運行時,它將在任何其他代碼運行之前完全運行。

當V8調用 JS  函數時,它必須將運行時數據存儲在某個地方。調用堆棧是內存中由堆棧幀組成的位置。每個堆棧幀對應于一個尚未被調用函數。堆棧結構由以下組成:

  • 局部變量

  • argument 參數

  • 返回地址

如果我們執行一個函數,V8 會將幀推到棧頂。當我們從一個函數返回時,V8 會跳出幀。

JavaScript內部原理是怎樣的

如上例所示,在每次函數調用時都會創建一個幀,并在每個return語句中將其刪除。

其他所有內容都動態地分配到一個稱為堆的大型非結構化內存塊中。

堆(Heap)

有時V8在編譯時不知道對象變量需要多少內存。此類數據的所有內存分配都發生在堆中。退出分配內存的函數后,堆上的對象繼續存在。

V8有一個內置的垃圾收集器(GC)。垃圾收集是內存管理的一種形式。它就像一個收集器,試圖釋放不再使用的對象占用的內存。換句話說,當一個變量失去所有引用時,GC將該內存標記為不可訪問并釋放它。

我們可以通過在Chrome開發工具中創建快照來研究堆。

JavaScript內部原理是怎樣的

實例化的每個 JS 對象都分組在其構造函數類下。括號中的分組表示不能直接調用的原生構造函數。可以看到有很多(編譯代碼)和(系統)實例,但也有一些傳統的  JS 對象,如Math、String、Array等。

瀏覽器運行時

V8可以根據標準,同步地使用一個調用堆棧來執行 JS  。但,我們需要渲染UI,需要處理用戶與UI的交互。此外,我們還需要在發出網絡請求時處理用戶交互,對此卻無能為力。當所有代碼都是同步的時候,我們如何實現并發呢?  這還得感謝瀏覽器引擎。

瀏覽器引擎負責用 HTML 和 CSS 渲染頁面。在 Chrome 中它被稱為Blink。它是WebCore的一個分支,Blink  是一個布局、渲染和文檔對象模型(DOM)庫。Blink 是用 c++  中實現的,它提供了DOM元素和事件、XMLHttpRequest、fetch、setTimeout、setInterval等 Web api,這些api可以通過  JS 訪問。

我們一起思考下面帶有setTimeout(onTimeout, 0)的示例:

JavaScript內部原理是怎樣的

可以看到,瀏覽器首先將f1()和f2()函數推入堆棧,然后執行onTimeout。那么上面的示例如何工作?

并發性

setTimeout函數執行后,瀏覽器引擎立即將setTimeout的回調函數放入一個事件表中。它是一個數據結構,將注冊的回調映射到事件,在我們的例子中是onTimeout函數映射到timeout事件。

一旦計時器到時,在本例中,我們將延遲設為0  ms,則立即觸發事件,并將onTimeout函數放入事件隊列(又名回調隊列,消息隊列或任務隊列)中。事件隊列是一種數據結構,由將來要處理的回調函數(任務)組成。

最后且重要的是,事件循環(一個不斷運行的循環)檢查調用堆棧是否為空。如果是,則執行從事件隊列中添加的第一個回調,從而移動到調用堆棧。

函數的處理將繼續,直到調用堆棧再次為空。然后,事件循環將處理事件隊列中的下一個回調(如果有的話)。

JavaScript內部原理是怎樣的

JavaScript內部原理是怎樣的

注意onResolve1、onResolve2和onTimeout回調的執行順序。

阻塞和非阻塞

簡單地說,所有 JS 代碼都被認為是阻塞的。當 V8 忙于處理堆棧幀時,瀏覽器被卡住了,應用程序的 UI 被阻塞。用戶將無法單擊、導航或滾動。直到 V8  完成它的工作,才會處理來自網絡請求的響應。

想象一下,我們如果在瀏覽器中運行的程序中解析圖像。

JavaScript內部原理是怎樣的

JavaScript內部原理是怎樣的

在上面的示例中,事件循環被阻止。它無法處理事件/作業隊列中的回調,因為調用堆棧包含這一幀。

Web API  為我們提供了通過異步回調來編寫非阻塞代碼的可能性。當調用像setTimeout或fetch這樣的函數時,我們把所有的工作委托給c++原生代碼,它在一個單獨的線程中運行。一旦操作完成,回調就被放入事件隊列。同時,V8可以繼續執行  JS 代碼。

使用這種并發模型,我們可以處理網絡請求、用戶與UI的交互等等,而不會阻塞 JS 執行線程。


對于希望能夠解決復雜任務的每個開發人員來說,理解 JS  環境由什么組成是至關重要的。現在我們知道了異步JavaScript是如何工作的,調用堆棧、事件循環、事件隊列和作業隊列在其并發模型中的角色。

你可能已經猜到的,在V8引擎和瀏覽器引擎后面還有很多工作要做。然而,我們大多數人只是需要對所有這些概念有一個基本的理解。

以上就是JavaScript內部原理是怎樣的,小編相信有部分知識點可能是我們日常工作會見到或用到的。希望你能通過這篇文章學到更多知識。更多詳情敬請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

黑河市| 台前县| 象州县| 文成县| 金寨县| 平江县| 会理县| 巴中市| 鹤山市| 井冈山市| 荆州市| 镇坪县| 永德县| 招远市| 农安县| 密云县| 济宁市| 建湖县| 泸水县| 邯郸市| 通渭县| 榆树市| 曲阜市| 吉隆县| 财经| 霍州市| 嵊泗县| 德保县| 哈密市| 仲巴县| 大关县| 大港区| 盱眙县| 石林| 军事| 秀山| 哈巴河县| 吉木乃县| 蓬安县| 溆浦县| 尚志市|