在我們前面理解了作用域之後,「作用域鏈」這個概念就產生了。那麼作用域鏈是什麼意思,它又是怎麼形成的,跟哪些概念有關係,這就是我接下來幾章想和大家**的內容:執行上下文、變數物件和作用域鏈。根據順序我們也可以看出來,想要理解作用域鏈,執行上下文是我們碰到的第乙個坎。
這一章我們就來討論一下到底什麼是執行上下文。
1. 定義
當 js 引擎開始執行預編譯生成的**時,就會進入到乙個執行上下文(executable code - 簡稱ec)。
在 ecma 標準規範裡並沒有從技術角度去定義 ec 的具體型別和結構,這個是在實現 ecmascript 引擎時需要考慮的問題。
但是在邏輯上,我們可以將活動的執行上下文看成乙個棧結構。棧底部永遠是全域性上下文(global context),而頂部就是當前活動的執行上下文。執行到當前**時,上下文入棧,執行完畢後,上下文出棧。
2. 可執行**有幾種
前面說到當引擎執行到可執行**的時候,就會將當前上下文壓入上下文棧中。那麼可執行的**又分為幾種?
在這裡,我們先假設定義執行上下文棧是乙個陣列:
ec = ;
複製**
第一種可執行** -- 全域性**:全域性型別**是在載入外部的 js 檔案或者本地 標籤中的**。注意,在全域性**中,並不包含定義在全域性環境 function 內的**。
程式啟動後進入初始化全域性環境:
ec = [
globalcontext
];複製**
第二種可執行** -- 函式**:當定義的函式被執行時,就進入了函式**,當前函式上下文被壓入 ec 棧中。注意,在函式**中,也不包含定義在該函式內部環境 function 內的**。
例如:
var a = 10;
function
foo ()
foo();
複製**
這個例子中的 ec 是什麼樣子的呢?
// 初始化
ec = [
globalcontext
];// 第一次呼叫 foo 函式
ec = [
functioncontext,
globalcontext
];// 在 foo 內遞迴呼叫自己
ec = [
functioncontext - recursively,
functioncontext,
globalcontext
];// 繼續遞迴呼叫自己
ec = [
......
functioncontext - recursively2,
functioncontext - recursively,
functioncontext,
globalcontext
];// 遞迴會不斷呼叫下去,因為沒有結束條件,所以這是乙個死迴圈
// 所以,ec 只會不斷增加新的上下文,但是卻不會退出
複製**
只有每次return的時候,才會退出當前執行上下文,相應上下文會從棧中彈出,棧指標會自動移動位置。
注意,當函式沒有明確指明 return 什麼的時候,預設 return undefined。
如果有丟擲的異常沒有被截獲的話,也有可能從乙個或多個執行上下文中退出。當所有**執行完以後,ec 中只會包含全域性上下文(global context),當程式退出以後,全域性上下文也會退出。
第三種可執行** -- eval **:eval 函式在呼叫的時候會產生上下文。 例如:
eval('var a = 10');
(function
foo () ());
alert(a); // 10
alert(b); // referenceerror,b is not defined
複製**
這個例子中 ec 的變化如下:
// 初始化
ec = [
globalcontext
];// eval('var a = 10');
ec = [
evalcontext,
globalcontext
];// eval 執行完畢
ec = [
globalcontext
];// 立即執行函式 foo
ec = [
functioncontext,
globalcontext
];// eval('var b = 20');
ec = [
evalcontext,
functioncontext,
globalcontext
];// eval 執行完畢
ec = [
functioncontext,
globalcontext
];// foo 執行完畢
ec = [
globalcontext
];複製**
這就是乙個典型的邏輯呼叫上下文棧。
在 settimeout 和 setinterval 函式中的第乙個引數也可以傳入**字串,但是這個一般不會這麼去用,所以這裡也就不討論了。
3. 結論
執行上下文環境是我們了解變數物件和作用域鏈的基礎,大家一定要好好理解(其實也並不難),下一節我們來討論變數物件,相信會讓大家有一定的收穫。
JS學習系列 05 執行上下文
在我們前面理解了作用域之後,作用域鏈 這個概念就產生了。那麼作用域鏈是什麼意思,它又是怎麼形成的,跟哪些概念有關係,這就是我接下來幾章想和大家 的內容 執行上下文 變數物件和作用域鏈。根據順序我們也可以看出來,想要理解作用域鏈,執行上下文是我們碰到的第乙個坎。這一章我們就來討論一下到底什麼是執行上下...
Js系列三 執行上下文
js 在執行的時候會進入乙個特定的環境中,這個環境被稱為執行上下文。在js中執行環境主要包括以下三種情況 1 全域性環境既js 執行時首先進入的環境。2 函式環境 函式執行時會進入當前函式的環境執行 由此我們知道在js程式執行過程中必然會出現多個執行環境 執行上下文 js引擎以函式呼叫棧的方式來處理...
js執行上下文與執行上下文棧
在了解js的執行上下文物件與執行上下文棧之前,我們要先了解兩個概念 即變數提公升跟函式提公升 變數提公升 通過var定義的變數,在定義語句之前我們就可以直接訪問到,不過它的值是undefined 函式提公升 通過function定義的函式,在函式定義語句前,我們就可以直接呼叫 變數提公升與函式提公升...