美文网首页
2018-01-07 执行上下文相关

2018-01-07 执行上下文相关

作者: 星火_txt | 来源:发表于2018-01-07 12:24 被阅读0次

    scope

    函数在创建时,会添加[[scope]]属性

    var x = 3
    function parent(){
    var x = 4
      function kid(){
       var x = 5
      }
    }
    

    parent的[[scope]] = [globalContext.VO]
    kid的[[scope]] = [parentConetext.AO,globalContext.VO]

    执行上下文 execution context

    • 在运行代码时,首先会创建一个执行上下文栈,假设是一个数组ECStack = [ ].
      当javascript执行代码时,首先遇到的是全局执行上下文,所以此时ECStack = [ globalContext ]
      只有当程序运行结束时,ECStack才会被清空,否则globalContext会一直在栈底.

    • 每当有一个函数运行,就将该函数的执行上下文压人该栈,运行结束时弹出.全局上下文始终在栈尾.

    function fun3() {
        console.log('fun3')
    }
    
    function fun2() {
        fun3();
    }
    
    function fun1() {
        fun2();
    }
    
    fun1();
    

    伪代码:

    // fun1()
    ECStack.push(<fun1> functionContext);
    
    // fun1中竟然调用了fun2,还要创建fun2的执行上下文
    ECStack.push(<fun2> functionContext);
    
    // 擦,fun2还调用了fun3!
    ECStack.push(<fun3> functionContext);
    
    // fun3执行完毕
    ECStack.pop();
    
    // fun2执行完毕
    ECStack.pop();
    
    // fun1执行完毕
    ECStack.pop();
    
    // javascript接着执行下面的代码,但是ECStack底层永远有个globalContext
    
    
    • 当函数运行时,会创建一个执行上下文,有this,scope,变量对象三个属性

    1. 变量对象(varialbe object)

    变量对象是与执行上下文的数据作用域,存储了在上下文中定义的变量和函数声明.

    function foo(a) {
      var b = 2;
      function c() {}
      var d = function() {};
    
      b = 3;
    
    }
    
    foo(1);
    

    运行代码至foo(1),时创建该函数的执行上下文,其中的变量对象为

    AO = {
      arguments: {
        0: 1,
      lenght: 1
      },
     a: 1,
     b: 3,
     c: function(){},
     d: reference to FunctionExpression "d"
    }
    

    2. 作用域链 scope chain

    当函数激活时,将活动对象添加到作用域链的前端
    Scope = [AO].concat([[scope]])

    3. this

    流程图/总结

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

    执行过程如下:

    1. checkscope 函数被创建,创建内部属性[[scope]]
    checkscope.[[scope]] = [
        globalContext.VO
    ];
    
    1. 执行 checkscope 函数,创建 checkscope 函数执行上下文,checkscope 函数执行上下文被压入执行上下文栈
    ECStack = [
        checkscopeContext,
        globalContext
    ];
    
    1. checkscope 函数并不立刻执行,开始做准备工作,第一步:复制函数[[scope]]属性创建作用域链
    checkscopeContext = {
        Scope: checkscope.[[scope]],
    }
    
    1. 第二步:用 arguments 创建活动对象,随后初始化活动对象,加入形参、函数声明、变量声明
    checkscopeContext = {
        AO: {
            arguments: {
                length: 0
            },
            scope2: undefined
        }
    }
    
    1. 第三步:将活动对象压入 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. 查找到 scope2 的值,返回后函数执行完毕,函数上下文从执行上下文栈中弹出
    ECStack = [
        globalContext
    ];
    

    原文: https://juejin.im/post/59278e312f301e006c2e1510

    相关文章

      网友评论

          本文标题:2018-01-07 执行上下文相关

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