JavaScript之呼叫棧

wade3po發表於2019-04-03

很早之前寫過棧和堆的結構,非常簡單的介紹了一下,主要是為了明白深拷貝和淺拷貝。最近突然發現了呼叫棧這個概念,理解這個概念對於一些函式的執行能更清晰的理解,比如遞迴。

棧(stack)是計算機中特殊的一個資料列表,棧有一個特點就是先進後出。我們可以把棧當做乒乓球的盒子,先放進去的最後才拿出來。今天只說說入棧和出棧兩個概念:

程式碼執行過程中會有呼叫棧(call stack)的概念,就是解析的機制,棧的一種執行結構。棧一定遵循先進後出。

有時候會讓自己鑽進牛角尖,比如棧是先進後出,那麼程式碼從上往下執行的時候,上面的程式碼先入棧,那麼為什麼上面的輸出會先執行?還有資料都是儲存在棧裡面,為什麼隨便可以取值?等等等等。

這些都是待研究的,這邊自己給了自己一個應該不正確的理解,棧有鏈式呼叫,就跟物件一樣,所以資料可以隨便呼叫。JavaScript執行上下文是按順序呼叫的,只有呼叫棧也叫作執行上下文棧才是先進後出。而執行上下文在JavaScript中跟作用域一樣,一個函式就是一個作用域,就是一個執行上下文。

看下面程式碼:

console.log('globals' + i);
var i = 1;
fn(1);
function fn(i) { 
 if(i == 4){      
   console.log('fns:'+ i);
 return    
}    
console.log('fns:' + i);
fn(i + 1); 
console.log('fne' + i);}
console.log('globale' + i);
複製程式碼

執行結果是:

globalsundefined
fns:1
fns:2
fns:3
fns:4
fne3
fne2
fne1
globale1
複製程式碼

程式碼執行的時候先生成一個window上下文執行棧,然後壓入棧中,接著執行到fn(1),把fn(1)壓入棧,fn(1)上下文執行,然後執行到fn(2),把fn(2)壓入棧,一直到fn(4),執行上下文棧裡面是這樣的:

JavaScript之呼叫棧
Window上下文按順序執行,輸出globalsundefined,fn(1)上下文按順序執行先輸出fns:1,然後就把fn(2)壓入棧了,所以就輸出fns2,依次一直到fn(4)。這就是入棧的過程。

然後開始出棧的執行,棧頂的先執行,當fn(4)執行完畢,就把fn(4)彈出棧,fn(3)就變成棧頂,fn(3)接著往下執行,輸出fne3,然後fn(3)彈出,依次一直到window。這就是出棧的過程。

執行上下文按順序執行,執行上下文棧(也叫呼叫棧)嚴格按照先進後出的順序執行。

按照正常的順序思維去理解或許更快更清晰得到答案,只是這些東西對於想要做些什麼的還是有必要去了解的。

解釋的不是很好,自己是明白了點,但是文字表述的不清楚,還有一些原理我自己也解釋不清,歡迎指教也歡迎留言。

Coding 個人筆記

JavaScript之呼叫棧

相關文章