美文网首页你不知道的JavaScriptJavaScript 进阶营
[JavaScript基础]作用域链和执行上下文

[JavaScript基础]作用域链和执行上下文

作者: 向布谷鸟说早安 | 来源:发表于2019-03-03 21:17 被阅读4次
    变量对象(函数创建过程生成)

    关键字:静态作用域链,AO
    Javacript是静态作用域链,也就确定了对变量查找的访问权限,是在被定义的时候就确定好的,也就是函数的作用域在函数定义的时候就决定了在,这个时候会生成变量对象AO,保存在下面所说的scope中。

    函数有一个内部属性 [[scope]],当函数创建的时候,就会保存所有父变量对象到其中,可以理解成 [[scope]] 就是所有父变量对象的层级链,但是注意:[[scope]] 并不代表完整的作用域链!

    函数创建的时候,保存的是根据词法所生成的作用域链,执行的时候,会复制这个作用域链,作为自己作用域链的初始化,然后根据环境生成变量对象,然后将这个变量对象,添加到这个复制的作用域链,这才完整的构建了自己的作用域链。至于为什么会有两个作用域链,是因为在函数创建的时候并不能确定最终的作用域的样子,为什么会采用复制的方式而不是直接修改呢?应该是因为函数会被调用很多次吧。
    静态作用域链详解

    执行上下文(函数执行过程)

    当javascript解析到可执行代码(全局代码、函数代码、eval代码)时,会创建执行上下文。
    关键字:变量提升,VO,AO
    每个执行上下文都有三个重要概念:
    变量对象(AO),作用域链(Scope Chain),this

    进入执行上下文后(也就是函数执行的时候),会先后把arguments对象,函数的形参,函数内声明的变量和函数放到AO中。
    VO = 函数声明 + 变量声明
    并且,变量声明是不影响函数声明的

    function test() {
        console.log(inner);
        function inner() {}
        var inner = 12;
    }
    
    test();
    

    输出:f inner

    AO = arguments + function parameters + VO
    并且,VO的声明是不影响前两者的。

    function test2(a) {
        console.log(a);
        var a = 13;
    }
    
    test2(function() {})
    

    输出: f()

    作用域链的理解

    在创建函数的时候,根据词法作用域,会初始化函数的[[scope]],存放函数父级的作用域链,在执行函数的时候,会创建函数的执行上下文,依次初始化函数的arguments对象,形参,函数内部的变量和函数,再加上之前初始化的[[scope]]构成了完整的函数作用域链。

    相关文章

      网友评论

        本文标题:[JavaScript基础]作用域链和执行上下文

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