調用棧是解釋器(就像瀏覽器中的javascript解釋器)追蹤函數執行流的一種機制。當執行環境中調用了多個函數時,經過這種機制,可以幫助咱們追蹤到哪一個函數正在執行,執行的函數體中又調用了哪一個函數。javascript
有關調用棧,你須要知道如下幾點:java
每調用一個函數,解釋器就會把該函數添加進調用棧並開始執行。瀏覽器
正在調用棧中執行的函數還調用了其它函數,那麼新函數也將被添加進調用棧,一旦這個函數被調用,便會當即執行。函數
當前函數執行完畢後,解釋器將其清出調用棧,繼續執行當前執行環境下的剩餘的代碼。spa
當分配的調用棧空間被佔滿時,會引起「堆棧溢出」。code
function greeting() {
// [1] 這裏有代碼哦~
sayHi();
// [2] 這裏也有代碼哦~
}
function sayHi() {
return "Hi!";
}
// 調用greeting函數
greeting();
// [3] 這裏還有代碼哦~
複製代碼
以上代碼會按照以下方式運行:ip
忽略前面全部函數,直到greeting()
函數被調用。get
把greeting()
添加進調用棧列表。string
調用棧列表 |
---|
greeting() |
執行greeting()
函數體中的全部代碼。it
代碼執行到sayHi()
時,該函數被調用
把sayHi()
添加進調用棧列表
調用棧列表 |
---|
greeting() |
sayHI() |
執行sayHi()
函數體中的代碼,直到所有執行完畢。
返回來繼續執行greeting()
函數體中sayHi()
後面的代碼。
刪除調用棧列表中的sayHi()
函數。
調用棧列表 |
---|
greeting() |
當greeting()
函數體中的代碼所有執行完畢,返回到激活greeting()
的代碼行,繼續執行剩餘JS代碼。
刪除調用棧列表中的greeting()
函數。
調用棧列表 |
---|
空 |
一開始,咱們獲得一個空空如也的調用棧。
隨後,每當有函數被調用都會自動地添加進調用棧,執行完函數體中的代碼後,調用棧又會自動地移除這個函數。
最後,咱們又獲得了一個空空如也的調用棧。