美文网首页
作用域链

作用域链

作者: jump_go | 来源:发表于2018-05-13 23:22 被阅读0次

    作用域链

    当函数被执行,便进入了自己的执行上下文,
    该执行上下文中的变量若并没有被找到,
    就会往上一层的作用域中去查找。
    直到该作用域的顶层(一般为全局环境中)
    

    JS权威指南中有一句很精辟的描述: ”JavaScript中的函数运行在它们被定义的作用域里,而不是它们被执行的作用域里.”

    由上可知,作用域链的规则确定,是函数在哪里声明在地方,而非被执行的作用域中。
    可以将此过程理解为,js引擎在解析js代码的时候就确定了函数的作用域链规则,而非是执行时产生的执行上下文而确定的作用域链。

    函数被声明时

    当函数被声明的时候,其函数内部有一个[[scope]]的属性,里面保存了该父作用域链级规则。

    函数声明和执行的过程

    以下为例

    var scope = "global scope";
    function checkscope(){
        var scope2 = 'local scope';
        return scope2;
    }
    checkscope();
    
    1. checkscope函数被创建时,作用域链相关规则被保存到内部属性[[scope]]中
    checkscope.[[scope]] = [
        globalContext.VO
    ];
    
    1. 执行checkscope函数,checkscope函数创建上下文(checkscopeContext)。checkscopeContext被push进执行上下文栈中,以便执行代码。

    2. checkscope函数并不马上执行,而是初始化活动对象,加入形参、函数声明、变量声明,复制作用域链并将活动对象压入 checkscope 作用域链顶端

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

    将活动对象压入 checkscope 作用域链顶端

    checkscopeContext = {
        AO: {
            arguments: {
                length: 0
            },
            scope2: undefined
        },
        Scope: [AO, [[Scope]]]
    }
    
    1. 始执行函数,随着函数的执行,修改 AO(变量对象) 的属性值
    checkscopeContext = {
        AO: {
            arguments: {
                length: 0
            },
            scope2: 'local scope'
        },
        Scope: [AO, [[Scope]]]
    }
    
    1. 执行完函数,并从执行上下文栈中弹出。

    作用域和执行上下文

    • 作用域规定了函数内部变量,和内部函数的可访问范围。js没有块级作用域,当生命一个函数的时候,就产生了一个局部作用域。是一套规则
    • 而执行上下文是,当函数在执行的时候,不仅仅是作用域和作用域链的访问规则。而是包括活动变量,形参等等的AO的环境。
    作用域链的规则,是当该函数在执行的时候,在自己本身的AO(变量对象)中找不到该变量,便遵循作用域链的规则往父作用域(该函数声明的地方就是其父作用域)中AO中寻找,该作用域链寻找一直到全局作用域中。

    相关文章

      网友评论

          本文标题:作用域链

          本文链接:https://www.haomeiwen.com/subject/mfvrdftx.html