变量对象

执行上下文的生命周期:
创建阶段:创建变量对象,建立作用域链,以及确定this的指向。
代码执行阶段:变量赋值,函数引用,以及执行其他代码。

变量对象的创建过程:
建立arguments对象。检查当前上下文中的参数,建立该对象下的属性与属性值。
检查当前上下文的函数声明,也就是使用function关键字声明的函数。以函数名建立属性,属性值为指向该函数所在内存地址的引用。如果函数名的属性已经存在,那么该属性将会被新的引用所覆盖。
检查当前上下文中的变量声明,每找到一个变量声明,就在变量对象中以变量名建立一个属性,属性值为undefined。如果该变量名的属性已经存在,为了防止同名的函数被修改为undefined,则会直接跳过,原属性值不会被修改。

testEC = {
    // 变量对象
    VO: {},
    scopeChain: {}
}

// VO 为 Variable Object的缩写,即变量对象
VO = {
    arguments: {...},  //注:在浏览器的展示中,函数的参数可能并不是放在arguments对象中,这里为了方便理解,我做了这样的处理
    foo: <foo reference>  // 表示foo的地址引用
    a: undefined
}

变量对象和活动对象有什么区别,他们其实都是同一个对象,只是处于执行上下文的不同生命周期。不过只有处于函数调用栈栈顶的执行上下文中的变量对象,才会变成活动对象。

// demo2
function test() {
    console.log(foo);
    console.log(bar);

    var foo = 'Hello';
    console.log(foo);
    var bar = function () {
        return 'world';
    }

    function foo() {
        return 'hello';
    }
}

test();

// 创建阶段
VO = {
    arguments: {...},
    foo: <foo reference>,
    bar: undefined
}
// 这里有一个需要注意的地方,因为var声明的变量当遇到同名的属性时,会跳过而不会覆盖

// 执行阶段
VO -> AO
VO = {
    arguments: {...},
    foo: 'Hello',
    bar: <bar reference>,
    this: Window
}

全局上下文有一个特殊的地方,它的变量对象,就是window对象

作者:这波能反杀
链接:https://www.jianshu.com/p/330b1505e41d
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

posted on 2019-08-10 14:00  bingery  阅读(91)  评论(0)    收藏  举报

导航