摘要:譯者注翻譯一個(gè)對(duì)新手比較友好的工作原理解析系列文章注意以下全部是概念經(jīng)驗(yàn)豐富的老鳥可以離場(chǎng)啦正文從這里開始隨著的流行團(tuán)隊(duì)們正在利用來支持多個(gè)級(jí)別的技術(shù)棧包括前端后端混合開發(fā)嵌入式設(shè)備以及更多這篇文章旨在成為深入挖掘和實(shí)際上他是怎么工作的系列
譯者注
翻譯一個(gè)對(duì)新手比較友好的 JavaScript 工作原理解析系列文章
注意: 以下全部是概念,經(jīng)驗(yàn)豐富的老鳥可以離場(chǎng)啦正文從這里開始
隨著 javascript 的流行,團(tuán)隊(duì)們正在利用javascript來支持多個(gè)級(jí)別的技術(shù)棧,包括前端,后端,混合開發(fā),嵌入式設(shè)備,以及更多
這篇文章旨在成為深入挖掘JavaScript和實(shí)際上他是怎么工作的系列文章中的第一篇:我們通過知道javascript的模塊(Building blocks)和他們?nèi)绾谓M合在一起工作來寫更好的代碼和應(yīng)用.我們還會(huì)分享一些我們構(gòu)建sessionStarck(這是一款主打反饋功能的產(chǎn)品)時(shí)的經(jīng)驗(yàn)法則,一款輕量級(jí)的javascript應(yīng)用為了保持競(jìng)爭(zhēng)力,必須時(shí)要健壯和高性能.
據(jù)githut stats(這是一個(gè)統(tǒng)計(jì)網(wǎng)站,根據(jù)gihub的數(shù)據(jù)來進(jìn)行語言統(tǒng)計(jì))的數(shù)據(jù)來看 , JavaScript 是github 上 活躍庫最多的,和提交數(shù)最多的語言,這讓他不會(huì)落后于其他類別.
如果項(xiàng)目變得如此依賴于JavaScript,這就意味著,為了開發(fā)驚艷的軟件(可以理解為程序),開發(fā)者不得不利用這個(gè)語言和生態(tài)系統(tǒng)(JavaScript生態(tài))提供的一切,對(duì)內(nèi)部的更深入和更深入的了解.
事實(shí)證明,有很大一部分的開發(fā)者每天都在使用javascript,但是卻不知道javascript 在底層干了啥(原文很長,其實(shí)就是這個(gè)意思,英文還真的是...)
Overview基本上每個(gè)人都知道 v8 引擎這個(gè)概念了,大多數(shù)人知道javascript 是一個(gè)單線程語言 或者是那個(gè)使用回調(diào)隊(duì)列的語言.
這篇文章,我們將跑通哪些概念的細(xì)節(jié)和說明javascript是如何運(yùn)行的,通過知道這些細(xì)節(jié),你能夠正確的使用提供的api書寫更好的,非阻塞的應(yīng)用.
如果你是一個(gè)javascript新手,這篇文章能讓你知道為什么javascript對(duì)比與其他語言,為什么如此神奇.
如果你是一個(gè)有經(jīng)驗(yàn)的javascript開發(fā)者,我也希望如此,這會(huì)給你一些關(guān)于javascript運(yùn)行時(shí)是怎么工作的閃亮的靈感(或者說新的見解).
javascript引擎google v8 引擎是一個(gè)了流行的例子,nodejs 和 chrome 都是使用這個(gè)引擎,這里是一個(gè)簡(jiǎn)單的他看起來是什么的圖
這個(gè)引擎看起來像是兩個(gè)組件.
memory Heap: 這是內(nèi)存分配的位置
call Stack: 這是你的代碼執(zhí)行時(shí),堆棧幀(starck frame)的位置
運(yùn)行時(shí)在瀏覽器中有一些api已經(jīng)被幾乎所有的javascript開發(fā)者使用了,例如 setTimeout 這些api,然而,他們不是又引擎提供的.
那么,他們從哪里來的呢?
其實(shí)這有點(diǎn)復(fù)雜.
看,我們有引擎,但是其實(shí)我們還有很多東西.我們有那些瀏覽器提供的web apis,例如 DOM, AJAX, setTimeout等等.
而且,我們還有流行的事件循環(huán)(even loop)和回調(diào)隊(duì)列(callback queue)
調(diào)用棧(回調(diào)隊(duì)列跟調(diào)用棧其實(shí)意思差不多,不過棧跟隊(duì)列是兩種不同的數(shù)據(jù)結(jié)構(gòu))javascript是一個(gè)單線程的編程語言(repeat又repeat,都說幾次了),這意味著他有一個(gè)調(diào)用棧,因此,他一次只能做一件事情.
調(diào)用棧是一個(gè)記錄了我們?cè)诔绦蛑械奈恢玫臄?shù)據(jù)結(jié)構(gòu),如果我們跳進(jìn)一個(gè)function,我們把這個(gè)函數(shù)放進(jìn)棧的頂部(棧是一種先進(jìn)后出的數(shù)據(jù)結(jié)構(gòu)),如果我們從function中return出來,我們就從棧的頂部跳了出來,這就是棧能做的事情.
讓我們來看一個(gè)例子:
function multiply(x, y) { return x * y; } function printSquare(x) { var s = multiply(x, x); console.log(s); } printSquare(5);
當(dāng)引擎執(zhí)行這段代碼的時(shí)候,調(diào)用棧(call stack)是空的,當(dāng)進(jìn)入printSquare的時(shí)候,棧上添加了一個(gè)函數(shù),在printSquare中我們又進(jìn)入了multiply中,此時(shí)棧的頂部又添加了一個(gè)函數(shù),當(dāng)我們從multiply中return的時(shí)候,棧就把頂部的函數(shù)彈出,此時(shí)我們就回到了printSquare里,然后執(zhí)行完printSquare后引擎自動(dòng)return undefined 以結(jié)束這個(gè)函數(shù)的執(zhí)行.
棧的每一次變化就想下面這樣:
棧中的每一個(gè)條目(entry)叫坐堆棧幀(stack frames)上面有提到
這就是一個(gè)異常拋出時(shí),棧追蹤是如何被構(gòu)造的(how stack traces are being constructed)---這取決于異常發(fā)生的時(shí)候,回調(diào)棧的狀態(tài).(突然跑異常去了,其實(shí)是想說明,異常就是通過調(diào)用棧實(shí)現(xiàn)的)
function foo() { throw new Error("SessionStack will help you resolve crashes :)"); } function bar() { foo(); } function start() { bar(); } start();
如果這段代碼在chrome執(zhí)行,會(huì)產(chǎn)生下邊的棧追蹤(其實(shí)就是一個(gè)錯(cuò)誤)
"棧壞了"(blowing the stack) --- 這發(fā)生在當(dāng)你把棧放滿了的時(shí)候(下面還說了一大推,還貼了代碼,其實(shí)就是死遞歸)
當(dāng)引擎執(zhí)行死遞歸的時(shí)候,會(huì)不停的調(diào)用同一個(gè)方法.看起來像下面這樣.
然而,函數(shù)在調(diào)用棧上調(diào)用的數(shù)量超過了調(diào)用棧的實(shí)際大小,瀏覽器決定要采取行動(dòng)了,所以他拋出了一個(gè)錯(cuò)誤,看起來是這樣的
在單線程上運(yùn)行代碼可以很容易,因?yàn)槟悴挥萌ヌ幚矶嗑€程中的復(fù)雜場(chǎng)景,例如,死鎖.
但是,運(yùn)行在單線程上也有他的限制,由于javascript只有一個(gè)調(diào)用棧,若是程序執(zhí)行得很慢怎么辦?
并發(fā)和事件循環(huán)(even loop)當(dāng)你有函數(shù)調(diào)用在調(diào)用棧(call stack)里為了一個(gè)任務(wù)花費(fèi)了大額的時(shí)間會(huì)發(fā)生什么?例如,想象一下,你要在瀏覽器了做一個(gè)復(fù)雜的圖片轉(zhuǎn)性(transfromation).
你可能會(huì)問--為什么這是一個(gè)問題?問題是調(diào)用棧有函數(shù)在運(yùn)行,瀏覽器就不能做其他的事情,這就造成了阻塞,這意味這瀏覽器不能渲染,它不能運(yùn)行任何的其他代碼,它卡住了,如果你想你的app 的ui界面流暢,那么這就是一個(gè)問題.
然而,這不是唯一的問題,一旦你的瀏覽器在調(diào)用棧開始了很多的任務(wù),這可能會(huì)在很長的一段時(shí)間內(nèi)失去響應(yīng).而很多的瀏覽器會(huì)拋出一個(gè)錯(cuò)誤,然后問你是否要關(guān)閉網(wǎng)頁.
現(xiàn)在,這不是一個(gè)最好的用戶體驗(yàn),對(duì)吧?
那么,我們要如何處理這種需要很長時(shí)間執(zhí)行的代碼呢?嗯~,解決辦法就是異步回調(diào)
這會(huì)再第二篇文章中詳細(xì)說明.
下面開始買他們產(chǎn)品的廣告了,就不翻譯了.
原文第二篇我會(huì)盡快翻譯,盡量不拖太久.
寫作新手,還望大家多多關(guān)注,多多點(diǎn)贊.
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/96533.html
摘要:自調(diào)用匿名函數(shù)打開源碼,首先你會(huì)看到這樣的代碼結(jié)構(gòu)這是一個(gè)自調(diào)用匿名函數(shù)。這樣子最大程度防止外界的變量定義對(duì)內(nèi)部造成影響 自調(diào)用匿名函數(shù) 打開jQuery源碼,首先你會(huì)看到這樣的代碼結(jié)構(gòu): (function(window,undefined){ //jquery code })(window); 這是一個(gè)自調(diào)用匿名函數(shù)。在第一個(gè)括號(hào)內(nèi),創(chuàng)建一個(gè)匿名函數(shù);第二個(gè)括號(hào)內(nèi),立...
摘要:調(diào)用棧是單線程編程語言,意味著它只有單一的調(diào)用棧。調(diào)用棧是一種數(shù)據(jù)結(jié)構(gòu),基本記錄了程序運(yùn)行的位置。舉個(gè)例子,先來看如下所示的代碼當(dāng)引擎開始執(zhí)行這段代碼時(shí),調(diào)用棧將是空的。這正是拋出異常時(shí)棧追蹤的構(gòu)造過程這基本上就是異常拋出時(shí)調(diào)用棧的狀態(tài)。 原文 How JavaScript works: an overview of the engine, the runtime, and the c...
摘要:判斷變量類型數(shù)據(jù)類型種操作符可能返回的值如下注意的能力有限,其對(duì)于類型返回的都是使用場(chǎng)景區(qū)分對(duì)象和原始類型要區(qū)分一種對(duì)象類型和另一種對(duì)象類型可以使用運(yùn)算符或?qū)ο髮傩赃\(yùn)算符用法左邊的運(yùn)算數(shù)是一個(gè)右邊運(yùn)算數(shù)是對(duì)象類的名字或者構(gòu)造函數(shù)返回或如果是 判斷變量類型 javaSctipt數(shù)據(jù)類型7種: Number, String, Boolean, Null, Undefined, Object...
摘要:譯者覺得作者的比喻很適合初學(xué)者理解,特此翻譯。進(jìn)一步說,回調(diào)觸發(fā)的順序是不能被保證的。所以我不必?fù)?dān)心代碼在同一時(shí)間訪問同一個(gè)數(shù)據(jù)結(jié)構(gòu)你確實(shí)理解了,這就是的單進(jìn)程事件循環(huán)設(shè)計(jì)美麗的地方。 前言 總括 :這篇文章十分生動(dòng)形象的的介紹了Node,滿足了讀者想去了解Node的需求。作者是Node的第一批貢獻(xiàn)者之一,德國前端大神。譯者覺得作者的比喻很適合初學(xué)者理解Node,特此翻譯。 譯者 :原...
摘要:深入系列第三篇,講解執(zhí)行上下文棧的是如何執(zhí)行的,也回答了第二篇中的略難的思考題。 JavaScript深入系列第三篇,講解執(zhí)行上下文棧的是如何執(zhí)行的,也回答了第二篇中的略難的思考題。 順序執(zhí)行? 如果要問到 JavaScript 代碼執(zhí)行順序的話,想必寫過 JavaScript 的開發(fā)者都會(huì)有個(gè)直觀的印象,那就是順序執(zhí)行,畢竟: var foo = function () { ...
閱讀 3727·2021-10-11 10:59
閱讀 1317·2019-08-30 15:44
閱讀 3489·2019-08-29 16:39
閱讀 2896·2019-08-29 16:29
閱讀 1812·2019-08-29 15:24
閱讀 817·2019-08-29 15:05
閱讀 1271·2019-08-29 12:34
閱讀 2350·2019-08-29 12:19