已經不敢自稱前端小白,曾經吹過的牛逼總要一點點去實現。javascript
正如前領導說的,本身喝酒吹過的牛皮,跪着都得含着淚去實現。前端
那麼沒有年終完美總結,來個新年莽撞開始可好。java
進擊巨人系列開篇,不忘初心,砥礪前行。git
執行上下文(Execution Context): 函數執行前進行的準備工做(也稱執行上下文環境)github
運行JavaScript代碼時,當代碼執行進入一個環境時,就會爲該環境建立一個執行上下文,它會在你運行代碼前作一些準備工做,如肯定做用域,建立局部變量對象等。編程
具體作了什麼先按下不表,先來看下JavaScript執行環境有哪些?數據結構
那麼與之對應的執行上下文類型一樣有3種:閉包
JavaScript運行時首先會進入全局環境,對應會生成全局上下文。程序代碼中基本都會存在函數,那麼調用函數,就會進入函數執行環境,對應就會生成該函數的執行上下文。函數
先插播一個知識點:"JS是單線程"! "單線程"! "單線程"!post
簡單理解下單線程,就是同個時間段只能作一件任務,完成以後才能夠繼續下一個任務。正如女友只有一個,各位面向對象的小夥伴們大家說對不對?有女票的必須說沒毛病。
既然是這樣,必需要有一個排隊機制,否則就會出現幾個流氓霸着車道不讓過,"還有王法麼?"
函數編程中,代碼中會聲明多個函數,對應的執行上下文也會存在多個。在JavaScript中,經過棧的存取方式來管理執行上下文,咱們可稱其爲執行棧,或函數調用棧(Call Stack)。
在說明執行棧前,先來補下"棧數據結構"知識點。
藉助前端大神的例子,用乒乓球盒子來理解棧的存取方式。(這個例子讓我完全記住了棧數據結構)
棧遵循"先進後出,後進先出"的規則,或稱LIFO ("Last In First Out") 規則。
如圖所示,咱們只能從棧頂取出或放入乒乓球,最早放進盒子的老是最後才能取出。
棧中"放入/取出",也可稱爲"入棧/出棧"。
總結棧數據結構的特色:
理解完棧的存取方式,咱們接着分析JavaScript中如何經過棧來管理多個執行上下文。
程序執行進入一個執行環境時,它的執行上下文就會被建立,並被推入執行棧中(入棧);
程序執行完成時,它的執行上下文就會被銷燬,並從棧頂被推出(出棧),控制權交由下一個執行上下文。
由於JS執行中最早進入全局環境,因此處於"棧底的永遠是全局環境的執行上下文"。而處於"棧頂的是當前正在執行函數的執行上下文",當函數調用完成後,它就會從棧頂被推出(理想的狀況下,閉包會阻止該操做,閉包後續文章深刻詳解)。
"全局環境只有一個,對應的全局執行上下文也只有一個,只有當頁面被關閉以後它纔會從執行棧中被推出,不然一直存在於棧底"
文字太多不如上代碼系列 ——》代碼 + 圖,一覽無遺:
function foo () { function bar () { return 'I am bar'; } return bar(); } foo();
執行上下文的生命週期有兩個階段:
建立階段(進入執行上下文)
執行階段(代碼執行)
建立階段:函數被調用時,進入函數環境,爲其建立一個執行上下文,此時進入建立階段
執行階段:執行函數中代碼時,此時執行上下文進入執行階段
Arguments
對象(並賦值)看到這裏,咱們不經會問變量對象是什麼鬼,它與代碼中常見的函數聲明,變量聲明有神馬關係???
當進入到一個執行上下文後,這個變量對象纔會被激活,因此叫活動對象(AO),這時候活動對象上的各類屬性才能被訪問。
"建立階段對函數聲明作賦值,變量及函數表達式僅作聲明,真正的賦值操做要等到執行上下文代碼執行階段"。
代碼例子1:變量提高
function foo() { console.log(a); // 輸出undefined var a = 'I am here'; // 賦值 } foo(); // 實際執行過程 function foo() { var a; // 變量聲明,var初始化undefined console.log(a); a = 'I am here'; // 變量從新賦值 }
代碼例子2:函數聲明優先級
function foo() { console.log(bar); var bar = 20; function bar() { return 10; } var bar = function() { return 30; } } foo(); // 輸出bar()整個函數聲明
執行上下文可存在多個,雖然沒有明確的數量限制,但若是超出棧分配的空間,會形成堆棧溢出。常見於遞歸調用,沒有終止條件形成死循環的場景。
// 遞歸調用自身 function foo() { foo(); } foo(); // 報錯: Uncaught RangeError: Maximum call stack size exceeded
參考文檔:
做者:以樂之名 本文原創,有不當的地方歡迎指出。轉載請指明出處。