原文地址:https://blog.sessionstack.com/how-does-javascript-actually-work-part-1-b0bacc073cf(需要翻牆)
隨著javascript變得越來越流行,很多團隊的技術棧都開始使用它,比如前端、後端、hybrid、嵌入式裝置等。
這篇文章是一個系列旨在深入瞭解JavaScript它實際上是如何執行的,我們認為,通過了解JavaScript的執行原理可以讓你編寫更好的程式碼和應用程式
如GitHut統計資料所示,JavaScript是活躍在頂部對於Repositories和Pushes,它不會落後太多其他類別。
如果專案越來越依賴於JavaScript,這意味著開發人員必須利用語言和生態系統提供的所有內容,對內部進行更深入的瞭解,以便構建出色的軟體。
事實證明,有很多開發人員每天都在使用JavaScript,但卻不瞭解幕後發生的事情。
概述
幾乎每個人都已經聽說過V8引擎作為一個引擎,大多數人都知道JavaScript是單執行緒的,或者它使用的是回撥佇列。
如果您對JavaScript比較陌生,那麼這篇博文將幫助您理解為什麼JavaScript與其他語言相比如此“奇怪”。
如果您是一位經驗豐富的JavaScript開發人員,希望它會為您提供一些關於JavaScript的新見解。
JavaScript 引擎
Google的V8是使用最廣泛的JavaScript引擎,它被使用在node.js和chrome瀏覽器當中,這是簡化後的樣子:
這個引擎包含兩個元件:
- 記憶體堆——這個是記憶體分配發生的地方
- 呼叫堆疊——這是JavaScript程式碼執行的資料幀所在的地方
執行時
有些API在瀏覽器中已經被幾乎所有的JavaScript開發人員使用過(比如:setTimeout),這些API並不是引擎所提供的。
那麼是來自哪兒的呢?事實證明,它是有點複雜。
呼叫堆疊
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的工作原理”系列中的第2部分進行更詳細的解釋:“V8引擎內部+關於如何編寫優化程式碼的5個技巧”。
後續文件翻譯會陸續跟進!!
歡迎關注玄說前端公眾號,後續將推出系列文章《一個大型圖形化應用0到1的過程》,此賬戶也將同步更新