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

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

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

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

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

思考題

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

// 思考題一:
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,可是仍是有些許差別的,本文就詳細的解析執行上下文棧執行上下文的具體變化過程。code

具體分析

咱們分析第一段代碼:對象

var scope = "global scope";
function checkscope(){
    var scope = "local scope";
    function f(){
        return scope;
    }
    return f();
}
checkscope();

執行過程以下:ip

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

ECStack = [
  globalContext
];

二、全局上下文初始化get

globalContext = {
  VO: [global],
  Scope: [globalContext.VO],
  this: globalContext.VO
}

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

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
]
相關文章
相關標籤/搜索