作用域鏈

作用域鏈

當函數(shù)被執(zhí)行,便進入了自己的執(zhí)行上下文,
該執(zhí)行上下文中的變量若并沒有被找到,
就會往上一層的作用域中去查找。
直到該作用域的頂層(一般為全局環(huán)境中)

JS權威指南中有一句很精辟的描述: ”JavaScript中的函數(shù)運行在它們被定義的作用域里,而不是它們被執(zhí)行的作用域里.”

由上可知,作用域鏈的規(guī)則確定,是函數(shù)在哪里聲明在地方,而非被執(zhí)行的作用域中。
可以將此過程理解為,js引擎在解析js代碼的時候就確定了函數(shù)的作用域鏈規(guī)則,而非是執(zhí)行時產(chǎn)生的執(zhí)行上下文而確定的作用域鏈。

函數(shù)被聲明時

當函數(shù)被聲明的時候,其函數(shù)內部有一個[[scope]]的屬性,里面保存了該父作用域鏈級規(guī)則。

函數(shù)聲明和執(zhí)行的過程

以下為例

var scope = "global scope";
function checkscope(){
    var scope2 = 'local scope';
    return scope2;
}
checkscope();
  1. checkscope函數(shù)被創(chuàng)建時,作用域鏈相關規(guī)則被保存到內部屬性[[scope]]中
checkscope.[[scope]] = [
    globalContext.VO
];
  1. 執(zhí)行checkscope函數(shù),checkscope函數(shù)創(chuàng)建上下文(checkscopeContext)。checkscopeContext被push進執(zhí)行上下文棧中,以便執(zhí)行代碼。

  2. checkscope函數(shù)并不馬上執(zhí)行,而是初始化活動對象,加入形參、函數(shù)聲明、變量聲明,復制作用域鏈并將活動對象壓入 checkscope 作用域鏈頂端

checkscopeContext = {
    AO: {
        arguments: {
            length: 0
        },
        scope2: undefined
    },
    Scope: checkscope.[[scope]],
}

將活動對象壓入 checkscope 作用域鏈頂端

checkscopeContext = {
    AO: {
        arguments: {
            length: 0
        },
        scope2: undefined
    },
    Scope: [AO, [[Scope]]]
}
  1. 始執(zhí)行函數(shù),隨著函數(shù)的執(zhí)行,修改 AO(變量對象) 的屬性值
checkscopeContext = {
    AO: {
        arguments: {
            length: 0
        },
        scope2: 'local scope'
    },
    Scope: [AO, [[Scope]]]
}
  1. 執(zhí)行完函數(shù),并從執(zhí)行上下文棧中彈出。

作用域和執(zhí)行上下文

  • 作用域規(guī)定了函數(shù)內部變量,和內部函數(shù)的可訪問范圍。js沒有塊級作用域,當生命一個函數(shù)的時候,就產(chǎn)生了一個局部作用域。是一套規(guī)則
  • 而執(zhí)行上下文是,當函數(shù)在執(zhí)行的時候,不僅僅是作用域和作用域鏈的訪問規(guī)則。而是包括活動變量,形參等等的AO的環(huán)境。
作用域鏈的規(guī)則,是當該函數(shù)在執(zhí)行的時候,在自己本身的AO(變量對象)中找不到該變量,便遵循作用域鏈的規(guī)則往父作用域(該函數(shù)聲明的地方就是其父作用域)中AO中尋找,該作用域鏈尋找一直到全局作用域中。
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容