Call Stack 調(diào)用堆棧
JavaScript 是一種單線程編程語言,這意味著它只有一個 Call Stack 锰悼。因此窘俺,它一次僅能做一件事。
Call Stack 是一個數(shù)據(jù)結(jié)構(gòu)矛绘,它基本上記錄了我們在程序中的所處的位置。如果我們進入一個函數(shù)刃永,我們把它放在堆棧的頂部货矮。如果我們從一個函數(shù)中返回,我們彈出堆棧的頂部斯够。這是所有的堆椙裘担可以做的東西。
我們來看一個例子雳刺〗僭睿看看下面的代碼:
function multiply(x, y) {
return x * y;
}
function printSquare(x) {
var s = multiply(x, x);
console.log(s);
}
printSquare(5);
當引擎開始執(zhí)行這個代碼時,Call Stack 將會變成空的掖桦。之后本昏,執(zhí)行的步驟如下:
Call Stack 的每個入口被稱為 Stack Frame(棧幀)。
這正是在拋出異常時如何構(gòu)建 stack trace 的方法 - 這基本上是在異常發(fā)生時的 Call Stack 的狀態(tài)枪汪∮磕拢看看下面的代碼:
function foo() {
throw new Error('SessionStack will help you resolve crashes :)');
}
function bar() {
foo();
}
function start() {
bar();
}
start();
如果這是在 Chrome 中執(zhí)行的(假設這個代碼在一個名為 foo.js 的文件中)怔昨,那么會產(chǎn)生下面的 stack trace:
“Blowing the stack”—當達到最大調(diào)用堆棧大小時,會發(fā)生這種情況宿稀。這可能會很容易發(fā)生趁舀,特別是如果你使用遞歸,而不是非常廣泛地測試你的代碼祝沸“耄看看這個示例代碼:
function foo() {
foo();
}
foo();
當引擎開始執(zhí)行這個代碼時,它首先調(diào)用函數(shù)“foo”罩锐。然而奉狈,這個函數(shù)是遞歸的,并且開始調(diào)用自己而沒有任何終止條件涩惑。所以在執(zhí)行的每個步驟中仁期,同一個函數(shù)會一次又一次地添加到調(diào)用堆棧中。它看起來像這樣:
https://www.oschina.net/translate/how-does-javascript-actually-work-part-1