js 变量对象 作用域链

来源:互联网 发布:java语言自学 编辑:程序博客网 时间:2024/06/05 09:36

可执行代码:全局、函数、eval
执行代码时创建的上下文类型:全局上下文、函数上下文、eval上下文
执行上下文(EC)属性:变量对象(vo)、this、作用域链(sc)
执行上下文栈

变量对象

用来存储:变量、声明式函数、形参

  • 全局对象:变量、声明式函数都存在window对象里面
  • 激活对象:Arguments Object

    • callee
    • length
    • [0]……[length-1]
  • 变量实例化
    优先级:声明式函数>函数形参>变量
    (实例化时添加的变量不可删)

var a=10; delate  //不可删window.a; delate  //可删

代码执行步骤:

  • 进入上下文
    • 初始化this 作用域链 变量对象
    • 变量实例化
  • 代码执行

作用域链

作用域链可以看做一个数组

  • 全局上下文的作用域链 [全局对象]
  • 函数上下文的作用域链 [当前激活对象+ function.[[scope]] ]

with 可以临时改变作用域链,因为多查找了一次变量,可能导致效率变低。

用一个例子来描述一下代码执行过程

EC:Execution Context 上下文
VO:variable objec 变量对象
SC:scope chain 作用域链
AO:activation object 激活对象

var y = 10;function test(){    var y = 2;    return function(){          alert(y);    }}var fun = test();fun();
  1. 创建上下文阶段

    初始化this、变量对象、作用域链,变量实例化

    ``` jsglobal EC={    VO: {        test : test_fun_objcet,        y : undefined,        fun : undefined    },    this : window,    SC : [window]}```

    此时的上下文栈 这里写图片描述

  2. 代码执行阶段

    global EC={    VO: {        test : test_fun_objcet,        y : 10,        fun : test_fun_objcet    },    this : window,    SC : [window]}

    执行fun() , 即test函数,

    • 同样是进入test的上下文,初始化this、变量对象、作用域链,变量实例化

      test EC={    VO: {        y : undefined    },    this : window,    SC : [testAO,window]    //SC = [ 当前激活对象 + function.[[scope]] ]    //其中激活对象是 testAO    //function.[[scope]]是函数创建时所在的SC,即[window]}

      此时的上下文栈 这里写图片描述

    • test执行阶段

      test EC={    VO: {        y : 2    },    this : window,    SC :[testAO,window]}

      返回匿名函数,

      • 创建匿名(anonymous)函数的上下文

        anonymous EC={    VO: { },    this : window,    SC : [anonymousAO,testAO, window]    //SC = [ 当前激活对象 + function.[[scope]] ]    //其中激活对象是 anonymousAO     //function.[[scope]]是函数创建时所在的SC,即[testAO,window]}

        此时的上下文栈这里写图片描述

      • 该匿名函数没有声明式函数、形参、变量,所以进入执行阶段
        alert(y), 在当前的SC中查找y,当前的SC=[anonymousAO,testAO, window],anonymousAO中没有y,testAO中y=2,所以弹出结果是 2。

end

0 0