深刻學習js之——執行上下文#7

深刻學習js系列是本身階段性成長的見證,但願經過文章的形式更加嚴謹、客觀地梳理js的相關知識,也但願可以幫助更多的前端開發的朋友解決問題,期待咱們的共同進步。前端

若是以爲本系列不錯,歡迎點贊、評論、轉發,您的支持就是我堅持的最大動力。數組


《深刻學習js之——執行上下文棧》中說過,當JavaScript代碼執行一段可執行代碼(executable code)時,會建立對應的執行上下文(execution context)微信

對於每個執行上下文,都有三個重要的屬性:閉包

變量對象(Variable object VO) 做用域鏈(Scope chain) thisapp

本文咱們結合着這三個部分的內容,講講執行上下文的具體處理過程。函數

思考題

《深刻學習js之——詞法做用域和動態做用域》中,提出這樣一道思考題:post

// 思考題一:
var scope = "global scope";
function checkscope(){
  var scope = "local scope";
  function f(){
    return scope;
  }
  return f();
}
checkscope();

// 思考題二:
var scope = "global scope";
function checkscope(){
    var scope = "local scope";
    function f(){
        return scope;
    }
    return f;
}
checkscope()();
複製代碼

兩段代碼都會打印local scope,可是仍是有些許差別的,本文就詳細的解析執行上下文棧執行上下文的具體變化過程。學習

具體分析

咱們分析第一段代碼:this

var scope = "global scope";
function checkscope(){
    var scope = "local scope";
    function f(){
        return scope;
    }
    return f();
}
checkscope();
複製代碼

執行過程以下:spa

一、執行全局代碼,建立全局執行上下文,全局上下文被壓入執行上下文棧

ECStack = [
  globalContext
];
複製代碼

二、全局上下文初始化

globalContext = {
  VO: [global],
  Scope: [globalContext.VO],
  this: globalContext.VO
}
複製代碼

二、初始化的同時,checkscope 函數被建立,保存做用域鏈到函數內部的屬性[[scope]]

checkscope.[[scope]] = [
  globalContext.VO
];
複製代碼

三、執行checkScope 函數,建立checkScope 函數執行上下文,checkScope 函數執行上下文被壓入執行上下文棧:

ECStack = [
  checkscopeContext,
  globalContext
];
複製代碼

四、checkscope 函數執行上下文初始化:

1.複製函數 [[scope]] 屬性建立做用域鏈, 2.用 arguments 建立活動對象, 3.初始化活動對象,即加入形參、函數聲明、變量聲明, 4.將活動對象壓入 checkscope 做用域鏈頂端,

同時 f 函數被建立,保存做用域鏈到 f 函數的內部屬性[[scope]]

checkscopeContext = {
  AO: {
      arguments: {
        length: 0
      },
      scope: undefined,
      f: reference to function f(){}
  },
  Scope: [AO, globalContext.VO],
  this: undefined
}
複製代碼

五、執行f函數,建立 f 函數執行上下文,f 函數執行上下文被壓入執行上下文棧

ECStack = [
    fContext,
    checkscopeContext,
    globalContext
  ]
複製代碼

六、f 函數執行上下文初始化, 如下跟第 4 步相同:

1.複製函數 [[scope]] 屬性建立做用域鏈 2.用 arguments 建立活動對象 3.初始化活動對象,即加入形參、函數聲明、變量聲明 4.將活動對象壓入 f 做用域鏈頂端

fContext = {
    AO: {
        arguments: {
            length: 0
        }
    },
    Scope: [AO, checkscopeContext.AO, globalContext.VO],
    this: undefined
  }
複製代碼

七、f 函數執行,沿着做用域鏈查找 scope 值,返回 scope 值

八、f 函數執行完畢,f 函數上下文從執行上下文棧中彈出

ECStack = [
  checkscopeContext,
  globalContext
]
複製代碼

九、checkscope 函數執行完畢,checkscope 執行上下文從執行上下文棧中彈出

ECStack = [
  globalContext
]
複製代碼

深刻學習JavaScript系列目錄

歡迎添加個人我的微信討論技術和個體成長。

歡迎關注個人我的微信公衆號——指尖的宇宙,更多優質思考乾貨

相關文章
相關標籤/搜索