变量对象VO
变量对象VO是与执行上下文相关的特殊对象,用来存储上下文的函数声明,函数形参和变量。在global全局上下文中,变量对象也是全局对象自身,在函数上下文中,变量对象被表示为活动对象AO。
变量对象VO存储上下文中声明的以下内容
{
函数声明FD(如果在函数上下文中),—-不包含函数表达式
函数形参function arguments,
变量声明–注意b=10不是变量,但是var b = 10;是变量,有变量声明提升
var a = 10; function test(x) { var b = 20; }; test(30); // 全局上下文的变量对象 VO(globalContext) = { a: 10, test: <reference to function> }; // test函数上下文的变量对象 VO(test functionContext) = { x: 30, b: 20 };
变量对象VO分类
全局上下文的变量对象VO,函数上下文的变量对象VO
//全局上下文的变量对象VO就是全局对象
VO(globalContext) === global;
活动变量AO
当函数被调用后,这个特殊的活动对象就被创建了。它包含普通参数与特殊参数对象(具有索引属性的参数映射表)。活动对象在函数上下文中作为变量对象使用。
在函数执行上下文中,VO是不能直接访问的,此时由活动对象(activation object,缩写为AO)扮演VO的角色
VO(functionContext) === AO;
Arguments对象是活动对象的一个属性,它包括如下属性:
callee — 指向当前函数的引用
length — 真正传递的参数个数
properties-indexes (字符串类型的整数) 属性的值就是函数的参数值(按参数列表从左到右排列)。
properties-indexes内部元素的个数等于arguments.length. properties-indexes 的值和实际传递进来的参数之间是共享的。
function foo(x, y, z) { console.log(foo.name); //foo // 声明的函数参数数量arguments (x, y, z) console.log(foo.length); // 3 // 真正传进来的参数个数(only x, y) console.log(arguments.length); // 2 // 参数的callee是函数自身 console.log(arguments.callee === foo); // true // 参数共享 console.log(x === arguments[0]); // true console.log(x); // 10 arguments[0] = 20; console.log(x); // 20 x = 30; console.log(arguments[0]); // 30 // 不过,没有传进来的参数z,和参数的第3个索引值是不共享的 z = 40; console.log(arguments[2]); // undefined arguments[2] = 50; console.log(z); // 40 } foo(10, 20);
处理上下文代码的2个阶段
进入执行上下文和执行代码
进入执行上下文:
变量是进入上下文阶段放入VO中,也就是变量声明提升并且变量声明顺序上是在函数声明和形参声明后
//变量声明在顺序上跟在函数声明和形式参数声明之后,而且在这个进入上下文阶段,变量声明不会干扰VO中已经存在的同名函数声明或形式参数声明 alert(x); // function var x = 10; alert(x); // 10 x = 20; function x() {}; alert(x); // 20
alert(x); // 20 var x = 10; alert(x); // 10 x = 20; function b(x) {}; alert(x); // 20
function test(a, b) { var c = 10; function d() {} var e = function _e() {}; (function x() {}); } test(10); // call 当进入带有参数10的test函数上下文时,AO表现为如下: //AO里并不包含函数“x”。这是因为“x” 是一个函数表达式(FunctionExpression, 缩写为 FE) 而不是函数声明,函数表达式不会影响VO AO(test) = { a: 10, b: undefined, c: undefined, d: <reference to FunctionDeclaration "d"> e: undefined };
//函数表达式不在AO中 console.log(x) // x is not defined (function x() {});