一个执行上下文可以抽象理解为object。每个执行上下文都有一系列的属性(可以称为上下文状态),他们用来追踪关联代码的执行进度。
Execution context | |
变量对象 | Vars,function declaration,arguments… |
作用域链 | variable object+all parent scopes |
this值 | Context object |
变量对象:
A variable object is a scope of data related with the execution context. It’s a special object associated with the context and which stores variables and function declarations are being defined within the context.
变量对象是一个抽象的概念,在不同的上下文中,它表示使用不同的object。例如,在global全局上下文中,变量对象也是全局对象自身【global object】。(这就是我们可以通过全局对象的属性来指向全局变量)
var foo = 10;
function b1() {}
var b2=function a(){};//这个也是函数表达式,不能通过a访问,因为函数表达式不包含于变量对象,但可以通过b2
(function b3() {});
console.log(
this.foo == foo, // true
window.b1 == b1,// true
window.b2==b2
);
console.log(b3); //报错Uncaught ReferenceError: b3 is not defined
Global VO | |
foo | 10 |
b1 | <function> |
b2 | <function> |
如上所示,函数“b3”如果作为函数表达式则不被包含于变量对象。这就是在函数外部尝试访问产生引用错误(ReferenceError)的原因。请注意,ECMAScript和其他语言相比(如c/c++),仅有函数能够创建新的作用域。使用eval的时候,我们会使用一个新的执行上下文。eval会使用全局变量对象或调用者的变量对象(eval的调用来源)。
活动对象:
当函数被调用后,这个特殊的活动对象就被创建了。它包含普通参数与特殊参数对象(具有索引属性的参数映射表)。活动对象在上下文中作为变量对象使用。
function foo(x, y) {
var z = 30;
function bar() {}
(function baz() {});
}
foo(10, 20);
Action object | |
x | 10 |
y | 20 |
arguments | {0:10,1:20,…} |
z | 30 |
bar | <function> |
函数表达式不在AO的行列