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

2018-01-07  本文已影响0人  星火_txt

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

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

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

上一篇 下一篇

猜你喜欢

热点阅读