摘要:工作機制第部分本文轉載自眾成翻譯譯者網絡埋伏紀事鏈接原文隨著越來越受歡迎,開發團隊正在將其用在技術棧的各個方面,包括前端后端混合應用嵌入式設備等等。之后,步驟將是如下這樣調用棧中的每個條目稱為棧幀。
JavaScript工作機制:第1部分
本文轉載自:眾成翻譯
譯者:網絡埋伏紀事
鏈接:http://www.zcfy.cc/article/3965
原文:https://blog.sessionstack.com/how-does-javascript-actually-work-part-1-b0bacc073cf
隨著JavaScript越來越受歡迎,開發團隊正在將其用在技術棧的各個方面,包括 - 前端、后端、混合應用、嵌入式設備等等。
如GitHut統計所示,JavaScript在GitHub中的活動存儲庫和總推送方面位于前列,在其他方面也不差。
(查看最新的GitHub語言統計信息)。
如果項目越來越依賴于JavaScript,這意味著開發人員必須更深入地了解內部機制,才能利用語言和生態系統提供的所有技術,構建出驚艷的軟件。
事實證明,雖然有很多開發人員每天都在使用JavaScript,但并不知道它的工作機制。
概述幾乎所有人都已經聽說過V8引擎的概念,大多數人都知道JavaScript是單線程的,或者是使用回調隊列。
在這篇文章中,我們將詳細介紹所有這些概念,并解釋JavaScript的工作機制。通過了解這些細節,您將能夠正確利用提供的API,編寫更好的非阻塞應用程序。
如果您是一個JavaScript新手,此博文將幫助您了解為什么JavaScript與其他語言相比是如此“怪異”。
而如果您是一位經驗豐富的JavaScript開發人員,希望能夠提供與您每天使用的JavaScript運行時有關的一些新鮮見解。
JavaScript引擎JavaScript引擎的一個流行示例是Google的V8引擎。例如,V8引擎在Chrome和Node.js中使用。如下是它看起來像什么的一個簡單視圖:
引擎由兩個主要組成部分組成:
內存堆 - 這是內存分配發生的地方
調用棧 - 這是您的代碼執行所在的棧幀
運行時瀏覽器中已經有幾個幾乎所有JavaScript開發人員都會使用的API(比如 setTimeout)。不過,這些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,這會出問題。
而這不是唯一的問題。一旦瀏覽器開始處理調用棧中的許多任務,它可能會停止響應很長時間。大多數瀏覽器通過引發一個錯誤來采取行動,詢問您是否要終止網頁。
現在,這不是最好的用戶體驗,對吧?
那么,如何執行繁重的代碼,而不阻塞UI并且不會使瀏覽器無響應呢?好吧,解決方案是異步回調。
我將在教程的第2部分中詳細介紹。敬請關注 :)
歡迎關注我的公眾號,關注前端文章:
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/84847.html
摘要:忍者級別的函數操作對于什么是匿名函數,這里就不做過多介紹了。我們需要知道的是,對于而言,匿名函數是一個很重要且具有邏輯性的特性。通常,匿名函數的使用情況是創建一個供以后使用的函數。 JS 中的遞歸 遞歸, 遞歸基礎, 斐波那契數列, 使用遞歸方式深拷貝, 自定義事件添加 這一次,徹底弄懂 JavaScript 執行機制 本文的目的就是要保證你徹底弄懂javascript的執行機制,如果...
摘要:從異步過程的角度看,函數就是異步過程的發起函數,事件監聽函數就是異步過程的回調函數。事件觸發時,表示異步任務完成,會將事件監聽器函數封裝成一條消息放到消息隊列中,等待主線程執行。 1.為什么JavaScript是單線程? JavaScript語言的一大特點就是單線程,也就是說,同一個時間只能做一件事。那么,為什么JavaScript不能有多個線程呢?這樣能提高效率啊。JavaScrip...
摘要:第一階段基礎階段基礎程序員重點把搞熟練核心是安裝配置基本操作目標能夠完成基本的系統安裝,簡單配置維護能夠做基本的簡單系統的開發能夠在中型系統中支持某個功能模塊的開發。本項不做重點學習,除非對前端有興趣。 第一階段:基礎階段(基礎PHP程序員) 重點:把LNMP搞熟練(核心是安裝配置基本操作) 目標:能夠完成基本的LNMP系統安裝,簡單配置維護;能夠做基本的簡單系統的PHP開發;能夠在P...
摘要:心塞塞根據規范,事件循環是通過任務隊列的機制來進行協調的。等便是任務源,而進入任務隊列的是他們指定的具體執行任務回調函數。然后當前本輪的結束,主線程可以繼續取下一個執行。 依然是:經濟基礎決定上層建筑。 說明 首先,旨在搞清常用的同步異步執行機制 其次,暫時不討論node.js的Event Loop執行機制,以下關于瀏覽器的Event Loop執行機制 最后,借鑒了很多前輩的研究文...
摘要:最近剛剛看完了你不知道的上卷,對有了更進一步的了解。你不知道的上卷由兩部分組成,第一部分是作用域和閉包,第二部分是和對象原型。附錄詞法這一章并沒有說明機制,只是介紹了中的箭頭函數引入的行為詞法。第章混合對象類類理論類的機制類的繼承混入。 最近剛剛看完了《你不知道的 JavaScript》上卷,對 JavaScript 有了更進一步的了解。 《你不知道的 JavaScript》上卷由兩部...
閱讀 3094·2021-08-03 14:05
閱讀 2140·2019-08-29 15:35
閱讀 678·2019-08-29 13:30
閱讀 3169·2019-08-29 13:20
閱讀 2531·2019-08-23 18:15
閱讀 1797·2019-08-23 14:57
閱讀 2213·2019-08-23 13:57
閱讀 1310·2019-08-23 12:10