做用域和執行上下文

注意文中所指做用域和執行上下文都有全局和局部之分,爲方便理解採用局部。
本文參考引自: 思否:執行上下文和做用域的理解

定義

做用域:
js中的做用域是詞法做用域,即由函數聲明時所在的位置決定的。segmentfault

執行上下文:
每次函數調用時,都會產生一個新的執行上下文環境。函數

深刻理解

做用域:
js中的做用域是詞法做用域,是在編譯階段就產生的,一整套函數標識符的訪問規則。做用域只是一個「空地盤」,其中並無真實的變量,可是卻定義了變量如何訪問的規則。this

做用域鏈本質上是一個指向變量對象的指針列表,它只引用不包含實際變量對象。定義了當變量訪問不到的時候如何向上查詢的一套規則。spa

執行上下文:
每次函數執行都會產生執行上下文,JavaScript引擎會以棧的方式來處理它們,這個棧,咱們稱其爲函數調用棧(call stack)。棧底永遠都是全局上下文,而棧頂就是當前處於活動狀態的正在執行的上下文,也稱爲活動對象(running execution context,圖中藍色的塊),區別與底下被掛起的上下文(變量對象)。指針

壓棧出棧

let fn, bar; // 一、進入全局上下文環境
bar = function(x) {
  let b = 5;
  fn(x + b); // 三、進入fn函數上下文環境
};
fn = function(y) {
  let c = 5;
  console.log(y + c); //四、fn出棧,bar出棧
};

bar(10); // 二、進入bar函數上下文環境

函數執行過程

創建執行上下文階段(發生在 函數被調用時 && 函數體內的代碼執行前 )code

PS:我的以爲這個階段也能夠叫編譯階段:首先js是解釋型語言,解釋一條執行一條。其次函數內部的代碼在執行前並無作特殊處理,好比函數體內有語法錯誤,只有調用了函數纔會報錯,而在初始化js解析的時候並無發生任何報錯信息。

一、 生成變量對象:建立 arguments 對象 --> 建立function函數聲明 --> 建立var變量聲明;
二、 生成做用域鏈
三、 肯定this的指向對象

函數執行階段blog

變量賦值,函數引用,執行其它代碼ip

做用域和執行上下文聯繫

由定義可知,做用域是在函數聲明的時候就肯定的一套變量訪問規則,而執行上下文是函數執行時才產生的一系列變量的集合體。也就是說做用域定義了執行上下文中的變量的訪問規則,執行上下文是在這個做用域規則的前提下執行代碼的。作用域

相關文章
相關標籤/搜索