《JavaScript高级程序设计》总结(五)—— 做用域链

先来复习一下,执行上下文的构成bash

执行上下文函数

  • 变量对象(Variable object,VO)
  • 做用域链(Scope chain)
  • this的指向

以前说了变量对象,如今来讲下另外两个this

做用域链(Scope chain)

通俗地讲,当声明一个函数时,局部做用域一级一级向上包起来,就是做用域链。spa

咱们从函数定义到执行一步一步来讲明code

当函数定义的时候

当函数被定义的时候,会读取函数内部的一个属性,[[scope]]属性来保存就会保存全部父变量对象到其中,能够理解 [[scope]] 就是全部父变量对象的层级链对象

function a(){
    function b(){
        
    }
}
复制代码

分析一下,当函数建立时,各自的[[scope]]为作用域

a.[[scope] = [
   globalContext.VO
]

b.[[scope]] = [
    aContext.AO,
    globalContext.VO
];
复制代码

当函数激活的时候

当函数激活的时候,建立VO/AO。并将其加入做用域链的第一位,做用域链(scope)到如今就建立完毕了string

写个例子结合函数的上下文,变量对象等知识说明下做用域链

var global = '全局变量'
function abs(){
    a = 1
    console.log(a)
}
abs()
复制代码

1.函数abs被建立,将做用域链保存到[[scope]]中it

abs.[[scope]] = [
     globalContext.VO
]
复制代码

2.abs函数开始执行,此时建立abs函数的执行上下文,并入栈io

ECstack = [
    absContext
    globalContext
]
复制代码

3.abs作正式执行前的准备工做,将[[scope]]属性做为做用域链,此时的abs执行上下文

absContext = {
     Scope: abs.[[scope]],
}
复制代码

4.初始化变量对象,VO/AO

absContext = {
    AO: {
        arguments: {
            length: 0
        },
        a: undefined
    },
    Scope:abs.[[scope]]
}
复制代码

5.将活动对象AO加到做用域链的顶端

absContext = {
    AO: {
        arguments: {
            length: 0
        },
        a: undefined
    },
    Scope:[AO,abs.[[scope]]]
}
复制代码

至此,准备工做完成

6.随着函数的进行,AO开始进行赋值工做

checkscopeContext = {
    AO: {
        arguments: {
            length: 0
        },
        a: 1
    },
    Scope: [AO, [[Scope]]]
}
复制代码

7.在做用域链中找到a的值并打印

8.abs执行完毕,abs的执行上下文栈弹出

ECstack = [
    globalContext
]
复制代码
相关文章
相关标签/搜索