摘要:本章會(huì)對(duì)語(yǔ)言引擎,運(yùn)行時(shí),調(diào)用棧做一個(gè)概述。調(diào)用棧只是一個(gè)單線程的編程語(yǔ)言,這意味著它只有一個(gè)調(diào)用棧。查看如下代碼當(dāng)引擎開(kāi)始執(zhí)行這段代碼的時(shí)候,調(diào)用棧會(huì)被清空。之后,產(chǎn)生如下步驟調(diào)用棧中的每個(gè)入口被稱為堆棧結(jié)構(gòu)。
原文請(qǐng)查閱這里,本文采用知識(shí)共享署名 4.0 國(guó)際許可協(xié)議共享,BY Troland。
本系列持續(xù)更新中,Github 地址請(qǐng)查閱這里。
這是 JavaScript 工作原理的第一章。本章會(huì)對(duì)語(yǔ)言引擎,運(yùn)行時(shí),調(diào)用棧做一個(gè)概述。
隨著 JavaScript 越來(lái)越流行,團(tuán)隊(duì)也利用其在他們諸如前端,后端,混合 apps,嵌入設(shè)備以及更多設(shè)備等開(kāi)發(fā)棧中的不同層面的支持。
本章系列的第一章,本系列旨在深入 JavaScript 并理解它是如何運(yùn)行的:我們認(rèn)為在了解 JavaScript 的構(gòu)建模塊和它們是如何捏合在一起工作之后你將會(huì)寫(xiě)出更好的代碼和 apps。我們將會(huì)分享一些當(dāng)在創(chuàng)建 SessionStack 時(shí)候的經(jīng)驗(yàn)法則,SessionStack 是一個(gè)輕量級(jí)的 JavaScript 程序它擁有強(qiáng)壯性和高性能的優(yōu)點(diǎn)以保持競(jìng)爭(zhēng)力。
正如 GitHut stats 所顯示的那樣,JavaScript 的活躍庫(kù)和總推送數(shù)在 Github 排名第一。其它方面的表現(xiàn)也不會(huì)比其它語(yǔ)言落下太多。
(點(diǎn)擊查看最新 Github 語(yǔ)言統(tǒng)計(jì))
如果工程非常依賴于 JavaScript,那么這意味著開(kāi)發(fā)者不得不使用 JavaScript 和其語(yǔ)言生態(tài)提供的一切事物,為了能夠創(chuàng)造出很酷的軟件,就得更加深入地了解 JavaScript 語(yǔ)言的內(nèi)部工作機(jī)制。
事實(shí)上,有很多開(kāi)發(fā)者在每天日常開(kāi)發(fā)中都會(huì)使用 JavaScript 但是卻不了解其底層的知識(shí)。
概述幾乎所有人都已經(jīng)聽(tīng)說(shuō)過(guò) V8 引擎的概念,并且很多人知道 JavaScript 是單線程的或者說(shuō)是使用回調(diào)隊(duì)列的。
在本章中,我將會(huì)詳細(xì)地過(guò)一下這些概念并解釋 JavaScript 的工作原理。有賴于了解這些細(xì)節(jié),通過(guò)合理地使用提供的 APIs 你將可能寫(xiě)出更好的,非阻塞的程序。
如果你是新手,本文將會(huì)幫助你理解為什么和其它語(yǔ)言比較 JavaScript 是不可思議的。
如果你是一個(gè)經(jīng)驗(yàn)豐富的 JavaScript 開(kāi)發(fā)者,但愿,它將會(huì)讓你更加深入地了解 JavaScript 運(yùn)行時(shí)工作原理。
JavaScript 引擎谷歌 V8 引擎是流行的 JavaScript 引擎之一。V8 引擎在諸如 Chrome 和 Node.js 內(nèi)部使用。這里有一個(gè)簡(jiǎn)單的視圖來(lái)描繪其大概。
引擎包括兩個(gè)主要組件:
動(dòng)態(tài)內(nèi)存管理 - 在這里分配內(nèi)存
調(diào)用棧-這里代碼執(zhí)行即是你的堆棧結(jié)構(gòu)
運(yùn)行時(shí)幾乎每個(gè) JavaScript 開(kāi)發(fā)者都使用過(guò)一些瀏覽器 API(比如 setTimeout)。然而這些 API并不是引擎所提供的。
那么它們從何而來(lái)?
事實(shí)上這個(gè)情況有點(diǎn)復(fù)雜呃。。
所以,除了引擎但是實(shí)際上還有更多其它方面的東西。有被稱為 Web API 的東西,這些 Web API 是由瀏覽器提供的,比如 DOM,AJAX,setTimeout 以及其它。
于是乎,就有了流行的事件循環(huán)和回調(diào)隊(duì)列。
調(diào)用棧JavaScript 只是一個(gè)單線程的編程語(yǔ)言,這意味著它只有一個(gè)調(diào)用棧。這樣它只能一次做一件事情。
調(diào)用棧是一種數(shù)據(jù)結(jié)構(gòu),里面會(huì)記錄我們?cè)诔绦蛑械拇蟾盼恢?。?dāng)執(zhí)行進(jìn)入一個(gè)函數(shù),把它置于棧的頂部。如果從函數(shù)中返回則從棧頂部移除函數(shù)。這就是調(diào)用棧所能夠做的事情。
舉個(gè)栗子。查看如下代碼:
function multiply(x, y) { return x * y; } function printSquare(x) { var s = multiply(x, x); console.log(s); } printSquare(5);
當(dāng)引擎開(kāi)始執(zhí)行這段代碼的時(shí)候,調(diào)用棧會(huì)被清空。之后,產(chǎn)生如下步驟:
調(diào)用棧中的每個(gè)入口被稱為堆棧結(jié)構(gòu)。
當(dāng)拋出異常的時(shí)候這正好是堆棧追蹤是如何被構(gòu)造出來(lái)的-當(dāng)發(fā)生異常的時(shí)候這基本上是調(diào)用棧的狀態(tài)。看下如下代碼:
function foo() { throw new Error("SessionStack will help you resolve crashes:)"); } function bar() { foo(); } function start() { bar(); } start();
如果在 Chrome 中執(zhí)行(假設(shè)代碼在 foo.js 的文件中),將會(huì)產(chǎn)生如下的堆棧追蹤:
"堆棧溢出"-當(dāng)你達(dá)到最大調(diào)用棧大小的時(shí)候發(fā)生。這種情況相當(dāng)容易發(fā)生,特別是當(dāng)你使用遞歸而沒(méi)有仔細(xì)地檢查代碼的時(shí)候。查看下如下代碼:
function foo() { foo(); } foo();
當(dāng)引擎開(kāi)始執(zhí)行這段代碼的時(shí)候,它開(kāi)始調(diào)用 foo 函數(shù)。這個(gè)函數(shù),然而,會(huì)遞歸并開(kāi)始調(diào)用其自身而沒(méi)有任何結(jié)束條件。所以在每步執(zhí)行過(guò)程中,調(diào)用堆棧會(huì)反復(fù)地添加同樣的函數(shù)。執(zhí)行過(guò)程如下所示:
在某一時(shí)刻,然而,調(diào)用堆棧中的函數(shù)調(diào)用次數(shù)超過(guò)了調(diào)用堆棧的實(shí)際大小,這樣瀏覽器決定拋出錯(cuò)誤的動(dòng)作,如下所示:
在單線程中運(yùn)行代碼會(huì)相當(dāng)輕松因?yàn)槟悴挥锰幚矶嗑€程環(huán)境中產(chǎn)生的一些復(fù)雜情況,比如死鎖。
但是在單線程運(yùn)行代碼也會(huì)有相當(dāng)?shù)南拗?。由?JavaScript 只有一個(gè)調(diào)用棧,如果運(yùn)行很慢會(huì)發(fā)生什么?
并發(fā)和事件循環(huán)當(dāng)你在調(diào)用棧中有函數(shù)為了完成運(yùn)行需要消耗大量的時(shí)間的時(shí)候會(huì)發(fā)生什么?例如,想象一下你想要在瀏覽器用 JavaScript 來(lái)執(zhí)行一些復(fù)雜的圖像轉(zhuǎn)化。
你或許會(huì)問(wèn)-為什么這也是個(gè)問(wèn)題?問(wèn)題是這樣的當(dāng)調(diào)用棧有函數(shù)需要執(zhí)行,瀏覽器實(shí)際上不能做其它任何事-它被阻塞了。這意味著瀏覽器不能夠執(zhí)行渲染,它不能夠運(yùn)行其它代碼,它卡住了。如果你想要在 app 中擁有酷炫的流暢 UI 體驗(yàn),這將會(huì)是個(gè)問(wèn)題。
這不會(huì)是唯一的問(wèn)題。一旦瀏覽器開(kāi)始在調(diào)用棧中執(zhí)行如此多的任務(wù),瀏覽器將會(huì)在相當(dāng)一段時(shí)間內(nèi)停止交互。大多數(shù)瀏覽器會(huì)拋出一個(gè)錯(cuò)誤,詢問(wèn)你是否關(guān)閉網(wǎng)頁(yè)。
現(xiàn)在,這并不是最好的用戶體驗(yàn),難道不是嗎?
因此,如何不阻塞 UI 且不讓瀏覽器停止響應(yīng)來(lái)執(zhí)行運(yùn)行緩慢的代碼呢?使用異步回調(diào)。
這將會(huì)在 『JavaScript 工作原理』 第二章:『在V8 引擎中如何寫(xiě)最佳代碼的 5 條小技巧』中進(jìn)行詳細(xì)闡述。
本系列持續(xù)更新中,Github 地址請(qǐng)查閱這里。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/95125.html
摘要:本章會(huì)對(duì)語(yǔ)言引擎,運(yùn)行時(shí),調(diào)用棧做一個(gè)概述。調(diào)用棧只是一個(gè)單線程的編程語(yǔ)言,這意味著它只有一個(gè)調(diào)用棧。查看如下代碼當(dāng)引擎開(kāi)始執(zhí)行這段代碼的時(shí)候,調(diào)用棧會(huì)被清空。之后,產(chǎn)生如下步驟調(diào)用棧中的每個(gè)入口被稱為堆棧結(jié)構(gòu)。 原文請(qǐng)查閱這里,本文采用知識(shí)共享署名 4.0 國(guó)際許可協(xié)議共享,BY Troland。 本系列持續(xù)更新中,Github 地址請(qǐng)查閱這里。 這是 JavaScript 工作原...
摘要:文件系統(tǒng)請(qǐng)求和相關(guān)請(qǐng)求都會(huì)放進(jìn)這個(gè)線程池處理其他的請(qǐng)求,如網(wǎng)絡(luò)平臺(tái)特性相關(guān)的請(qǐng)求會(huì)分發(fā)給相應(yīng)的系統(tǒng)處理單元參見(jiàn)設(shè)計(jì)概覽。 譯者按:在 Medium 上看到這篇文章,行文脈絡(luò)清晰,闡述簡(jiǎn)明利落,果斷點(diǎn)下翻譯按鈕。第一小節(jié)背景鋪陳略啰嗦,可以略過(guò)。剛開(kāi)始我給這部分留了個(gè) blah blah blah 直接翻后面的,翻完之后回頭看,考慮完整性才把第一節(jié)給補(bǔ)上。接下來(lái)的內(nèi)容干貨滿滿,相信對(duì) N...
摘要:調(diào)用棧是一種數(shù)據(jù)結(jié)構(gòu),它記錄了我們?cè)诔绦蛑械奈恢?。?dāng)從這個(gè)函數(shù)返回的時(shí)候,就會(huì)將這個(gè)函數(shù)從棧頂彈出,這就是調(diào)用棧做的事情。而且這不是唯一的問(wèn)題,一旦你的瀏覽器開(kāi)始處理調(diào)用棧中的眾多任務(wù),它可能會(huì)停止響應(yīng)相當(dāng)長(zhǎng)一段時(shí)間。 原文地址: https://blog.sessionstack.com... PS: 好久沒(méi)寫(xiě)東西了,最近一直在準(zhǔn)備寫(xiě)一個(gè)自己的博客,最后一些技術(shù)方向已經(jīng)敲定了,又可以...
摘要:本章將會(huì)深入谷歌引擎的內(nèi)部結(jié)構(gòu)。一個(gè)引擎可以用標(biāo)準(zhǔn)解釋程序或者即時(shí)編譯器來(lái)實(shí)現(xiàn),即時(shí)編譯器即以某種形式把解釋為字節(jié)碼。引擎的由來(lái)引擎是由谷歌開(kāi)源并以語(yǔ)言編寫(xiě)。注意到?jīng)]有使用中間字節(jié)碼來(lái)表示,這樣就不需要解釋器了。 原文請(qǐng)查閱這里,略有刪減。 本系列持續(xù)更新中,Github 地址請(qǐng)查閱這里。 這是 JavaScript 工作原理的第二章。 本章將會(huì)深入谷歌 V8 引擎的內(nèi)部結(jié)構(gòu)。我們也會(huì)...
摘要:理解執(zhí)行上下文和執(zhí)行堆棧對(duì)于理解的其它概念如提升,范圍和閉包至關(guān)重要。正確地理解執(zhí)行上下文和執(zhí)行堆棧將幫助你更好地使用開(kāi)發(fā)應(yīng)用。引擎執(zhí)行位于執(zhí)行堆棧頂部的方法。當(dāng)調(diào)用時(shí),為該函數(shù)創(chuàng)建一個(gè)新的執(zhí)行上下文,并且把它推入到當(dāng)前執(zhí)行堆棧。 By Sukhjinder Arora | Aug 28, 2018 原文 如果你是或者你想要成為一名js開(kāi)發(fā)者,那么你必須了解js程序內(nèi)部的運(yùn)作。理解執(zhí)行...
閱讀 1980·2021-11-24 10:45
閱讀 1468·2021-11-18 13:15
閱讀 4562·2021-09-22 15:47
閱讀 3941·2021-09-09 11:36
閱讀 2018·2019-08-30 15:44
閱讀 3097·2019-08-29 13:05
閱讀 2510·2019-08-29 12:54
閱讀 2003·2019-08-26 13:47