JavaScript 對引擎、運行時、調用堆棧的概述理解

JavaScript 對引擎、運行時、調用堆棧的概述理解

 隨着JavaScript愈來愈流行,愈來愈多的團隊普遍的把JavaScript應用到前端、後臺、hybrid 應用、嵌入式等等領域。html

這篇文章旨在深刻挖掘JavaScript,以及向你們解釋JavaScript是如何工做的。咱們經過了解它的底層構建以及它是怎麼發揮做用的,能夠幫助咱們寫出更好的代碼與應用。據 GitHut 統計顯示,JavaScript 長期佔據GitHub中 Active Repositories 和 Total Pushes 的榜首,而且在其餘的類別中也不會落後太多。前端

若是一個項目愈來愈依賴 JavaScript,這就意味着開發人員必須利用這些語言和生態系統提供更深層次的核心內容去構建一個使人振奮的應用。然而,事實證實,有不少的開發者天天都在使用 JavaScript,可是殊不知道在底層 JavaScript 是怎麼運做的。java

概述web

幾乎每一個人據說過 V8 引擎的概念,並且,大多數人都知道 JavaScript 是單線程的,或者是它是使用回調隊列的。
在這篇文章中,咱們將詳細的介紹這些概念,並解釋 JavaScript 是怎麼工做的。經過了解這些細節,你就能利用這些提供的 API 來寫出更好的,非阻塞的應用來。若是你對 JavaScript 比較陌生,那麼這篇文章將幫助您理解爲何 JavaScript 相較於其餘語言顯得如此「怪異」。若是您是一位經驗豐富的 JavaScript 開發人員,但願它能給你帶來一些新的看法,說明 JavaScript 的運行時,儘管你可能天天都會用到它。瀏覽器

JavaScript 引擎數據結構

JavaScript 引擎提及來最流行的固然是谷歌的 V8 引擎了, V8 引擎使用在 Chrome 以及 Node 中,下面有個簡單的圖能說明他們的關係:多線程

這個引擎主要由兩部分組成:併發

  • 內存堆:這是內存分配發生的地方
  • 調用棧:這是你的代碼執行時的地方

運行時函數

有些瀏覽器的 API 常常被使用到(好比說:setTimeout),可是,這些 API 卻不是引擎提供的。那麼,他們是從哪兒來的呢?事實上這裏面實際狀況有點複雜。工具

因此說咱們還有不少引擎以外的 API,咱們把這些稱爲瀏覽器提供的 Web API,好比說 DOM、AJAX、setTimeout等等。

而後咱們還擁有如此流行的事件循環和回調隊列。

調用棧

JavaScript 是一門單線程的語言,這意味着它只有一個調用棧,所以,它同一時間只能作一件事。

調用棧是一種數據結構,它記錄了咱們在程序中的位置。若是咱們運行到一個函數,它就會將其放置到棧頂。當從這個函數返回的時候,就會將這個函數從棧頂彈出,這就是調用棧作的事情。

讓咱們來看一看下面的例子:

function multiply(x, y) {
return x * y;
}
function printSquare(x) {
var s = multiply(x, x);
console.log(s);
}
printSquare(5);

當程序開始執行的時候,調用棧是空的,而後,步驟以下:

每個進入調用棧的都稱爲__調用幀__。

這能清楚的知道當異常發生的時候堆棧追蹤是怎麼被構造的,堆棧的狀態是如何的。讓咱們看一下下面的代碼:

function foo() {
throw new Error('SessionStack will help you resolve crashes :)');
}
function bar() {
foo();
}
function start() {
bar();
}
start();

若是這發生在 Chrome 裏(假設這段代碼實在一個名爲 foo.js 的文件中),那麼將會生成如下的堆棧追蹤:

"堆棧溢出",當你達到調用棧最大的大小的時候就會發生這種狀況,並且這至關容易發生,特別是在你寫遞歸的時候卻沒有全方位的測試它。咱們來看看下面的代碼:

function foo() {
foo();
}
foo();

當咱們的引擎開始執行這段代碼的時候,它從 foo 函數開始。而後這是個遞歸的函數,而且在沒有任何的終止條件的狀況下開始調用本身。所以,每執行一步,就會把這個相同的函數一次又一次地添加到調用堆棧中。而後它看起來就像是這樣的:

而後,在某一時刻,調用棧中的函數調用的數量超過了調用棧的實際大小,瀏覽器決定幹掉它,拋出一個錯誤,它看起來就像是這樣:

 

 

 

在單個線程上運行代碼很容易,由於你沒必要處理在多線程環境中出現的複雜場景——例如死鎖。可是在一個線程上運行也很是有限制。因爲 JavaScript 只有一個調用堆棧,當某段代碼運行變慢時會發生什麼?

併發與事件循環

調用棧中的函數調用須要大量的時間來處理,那麼這會發生什麼狀況呢?例如,假設你想在瀏覽器中使用 JavaScript 進行一些複雜的圖片轉碼。

你可能會問?這算什麼問題?事實上,問題是當調用棧有函數要執行,瀏覽器就不能作任何事,它會被堵塞住。這意味着瀏覽器不能渲染,不能運行其餘的代碼,它被卡住了。若是你想在應用裏讓 UI 很流暢的話,這就會產生問題。

並且這不是惟一的問題,一旦你的瀏覽器開始處理調用棧中的衆多任務,它可能會中止響應至關長一段時間。大多數瀏覽器都會這麼作,報一個錯誤,詢問你是否想終止 web 頁面。

總結

以上所述是小編給你們介紹的JavaScript 對引擎、運行時、調用堆棧的概述理解,但願對你們有所幫助,若是你們有任何疑問請給我留言,小編會及時回覆你們的。在此也很是感謝你們對腳本之家網站的支持!

您可能感興趣的文章:

文章同步發佈: https://www.geek-share.com/detail/2751296348.html

相關文章
相關標籤/搜索