JS入門難點解析4-執(zhí)行上下文棧

(注1:如果有問題歡迎留言探討,一起學(xué)習(xí)!轉(zhuǎn)載請注明出處,喜歡可以點個贊哦P偷省)
(注2:更多內(nèi)容請查看我的目錄。)

1. 簡介

在本系列的第二篇文章JS入門難點解析2-JS的變量提升和函數(shù)提升中嘱函,我們已經(jīng)討論過甘畅。之所以不說JS需要編譯,只是它不像其他編譯語言一樣需要翻譯成等價的另一種語言。但是仍然需要進行語法分析和代碼生成疏唾,并且通常是立即執(zhí)行蓄氧。而且,JS的變量提升和函數(shù)提升就發(fā)生在編譯階段槐脏。

回顧一下:

var foo = function () {
    console.log('foo1');
}
foo();  // foo1
var foo = function () {
    console.log('foo2');
}
foo(); // foo2

以及

function foo() {
    console.log('foo1');
}
foo();  // foo2
function foo() {
    console.log('foo2');
}
foo(); // foo2

這兩段代碼喉童,前一段進行了變量聲明提升,后一段進行了函數(shù)聲明提升顿天。我們講到過堂氯,這是因為 JavaScript 編譯器和引擎并非一行一行地分析和執(zhí)行程序,而是一段一段地分析執(zhí)行牌废。當分析執(zhí)行一段代碼的時候蜜托,會進行一個“準備工作”效览,包括變量聲明提升和函數(shù)聲明提升等。那么這里所謂的一段指的是什么呢获印?到底JavaScript編譯器和引擎遇到一段怎樣的代碼時才會做“準備工作”呢谬哀?這就需要了解什么是可執(zhí)行代碼了铜异。

2. 可執(zhí)行代碼

JavaScript 的可執(zhí)行代碼(executable code)有以下三類:全局代碼败京、函數(shù)代碼陪腌、eval代碼

當JS引擎遇到這三類代碼時莫绣,會開始做準備工作,創(chuàng)建一個“執(zhí)行上下文(execution context)"悠鞍。

舉例說明对室,當JS執(zhí)行到一個函數(shù)的時候,就會創(chuàng)建該函數(shù)的“執(zhí)行上下文(execution context)"咖祭。那么問題來了掩宜,JS代碼中可能出現(xiàn)為數(shù)眾多的函數(shù),如何管理創(chuàng)建的那么多執(zhí)行上下文呢么翰?

3. 執(zhí)行上下文棧

JavaScript 引擎創(chuàng)建了執(zhí)行上下文棧(Execution context stack牺汤,ECS)來管理執(zhí)行上下文。

為了模擬執(zhí)行上下文棧的行為浩嫌,讓我們定義執(zhí)行上下文棧是一個數(shù)組:

ECStack = [];

試想當 JavaScript 開始要解釋執(zhí)行代碼的時候檐迟,最先遇到的就是全局代碼,所以初始化的時候首先就會向執(zhí)行上下文棧壓入一個全局執(zhí)行上下文码耐,我們用 globalContext 表示它追迟,并且只有當整個應(yīng)用程序結(jié)束的時候,ECStack 才會被清空骚腥,所以 ECStack 最底部永遠有個 globalContext敦间。

ECStack = [
    globalContext
];

現(xiàn)在 JavaScript 遇到下面的這段代碼了:

function fun3() {
    console.log('fun3')
}
function fun2() {
    fun3();
}
function fun1() {
    fun2();
}
fun1();

執(zhí)行一個函數(shù)的時候,就會創(chuàng)建一個執(zhí)行上下文,并且壓入執(zhí)行上下文棧廓块,當函數(shù)執(zhí)行完畢的時候厢绝,就會將函數(shù)的執(zhí)行上下文從棧中彈出。知道了這樣的工作原理带猴,讓我們來看看如何處理上面這段代碼:

// 偽代碼

// fun1()
ECStack.push(<fun1> functionContext);

// fun1中調(diào)用了fun2昔汉,還要創(chuàng)建fun2的執(zhí)行上下文
ECStack.push(<fun2> functionContext);

// fun2還調(diào)用了fun3
ECStack.push(<fun3> functionContext);

// fun3執(zhí)行完畢
ECStack.pop();

// fun2執(zhí)行完畢
ECStack.pop();

// fun1執(zhí)行完畢
ECStack.pop();

// javascript接著執(zhí)行下面的代碼,但是ECStack底層永遠有個globalContext

參考

JavaScript深入之執(zhí)行上下文棧
JS代碼執(zhí)行機制

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末浓利,一起剝皮案震驚了整個濱河市挤庇,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌贷掖,老刑警劉巖嫡秕,帶你破解...
    沈念sama閱讀 218,122評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異苹威,居然都是意外死亡昆咽,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評論 3 395
  • 文/潘曉璐 我一進店門牙甫,熙熙樓的掌柜王于貴愁眉苦臉地迎上來掷酗,“玉大人,你說我怎么就攤上這事窟哺⌒汉洌” “怎么了?”我有些...
    開封第一講書人閱讀 164,491評論 0 354
  • 文/不壞的土叔 我叫張陵且轨,是天一觀的道長浮声。 經(jīng)常有香客問我,道長旋奢,這世上最難降的妖魔是什么泳挥? 我笑而不...
    開封第一講書人閱讀 58,636評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮至朗,結(jié)果婚禮上屉符,老公的妹妹穿的比我還像新娘。我一直安慰自己锹引,他們只是感情好矗钟,可當我...
    茶點故事閱讀 67,676評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著嫌变,像睡著了一般真仲。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上初澎,一...
    開封第一講書人閱讀 51,541評論 1 305
  • 那天秸应,我揣著相機與錄音虑凛,去河邊找鬼。 笑死软啼,一個胖子當著我的面吹牛桑谍,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播祸挪,決...
    沈念sama閱讀 40,292評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼锣披,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了贿条?” 一聲冷哼從身側(cè)響起雹仿,我...
    開封第一講書人閱讀 39,211評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎整以,沒想到半個月后胧辽,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,655評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡公黑,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,846評論 3 336
  • 正文 我和宋清朗相戀三年邑商,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片凡蚜。...
    茶點故事閱讀 39,965評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡人断,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出朝蜘,到底是詐尸還是另有隱情恶迈,我是刑警寧澤,帶...
    沈念sama閱讀 35,684評論 5 347
  • 正文 年R本政府宣布谱醇,位于F島的核電站暇仲,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏枣抱。R本人自食惡果不足惜熔吗,卻給世界環(huán)境...
    茶點故事閱讀 41,295評論 3 329
  • 文/蒙蒙 一辆床、第九天 我趴在偏房一處隱蔽的房頂上張望佳晶。 院中可真熱鬧,春花似錦讼载、人聲如沸轿秧。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,894評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽菇篡。三九已至,卻和暖如春一喘,著一層夾襖步出監(jiān)牢的瞬間驱还,已是汗流浹背嗜暴。 一陣腳步聲響...
    開封第一講書人閱讀 33,012評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留议蟆,地道東北人闷沥。 一個月前我還...
    沈念sama閱讀 48,126評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像咐容,于是被迫代替她去往敵國和親舆逃。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,914評論 2 355

推薦閱讀更多精彩內(nèi)容