一. 执行环境(execution context):是个抽象概念,执行环境定义了变量的或函数访问其他数据的的权限.
所有javascript代码都是在一个执行环境中被执行的,每个函数都有自己的执行环境,首先默认进入全局执行环境,接着调用一个函数,则就会创建一个新的执行环境,当调用函数返回后,执行过程会返回原始的执行环境,因此,运行中的javascript代码就构成了一个执行环境栈。在栈底部永远都是全局上下文(global content),而栈顶就是当前(活动的)执行上下文。
在javascript里面执行环境分为两类,一类是全局环境,一类是局部环境,整个页面里被共享的方法和属性就是在全局环境,相对于全局环境,函数{}号里的执行环境就是局部环境,某个执行环境中的所有代码执行完毕后,该环境被销毁,保存在其中的所有变量和函数定义也随之销毁。
执行环境也可以分为创建(进入执行上下文,即代码执行之前)和执行代码两个阶段。在创建阶段,解析器首先会创建一个变量对象(variable object),是一个与执行上下文相关的特殊对象,它存储着上下文中声明的以下内容:
执行环境中的变量(var):由名称和对应值(undefined)组成的一个变量对象的属性被创建;
函数声明:
函数参数:由名称和对应值组成的一个变量对象的属性被创建,如果没有传递对应参数的话,那么由名称和undefined值组成的一种变量对象的属性也将被创建。
在执行阶段,代码被解释执行,相应的,活动对象Active object/Variable Object变量对象会被做相应的修改。
function test(a,b){ var c=10; function d(){ var e=function ee(){};//ee也是一个函数表达式,但它分配给了变量e,所以可以通过变量e来访问 (function x(){}); //AO中并不包含x,因为它是一个函数表达式 }; } test(10);
当进入test的函数的执行上下文阶段,还没开始执行代码,此时的活动对象是
Active object(test)={
a:10,//函数的形参
b:undefined,//函数的另一个形参
c:undefined,//变量声明
d :<reference to Function Declaration>,//函数声明
e :undefined,//变量声明
};
代码执行阶段,AO/VO已经有了属性(不是所有的属性都有值,大部分属性的值还是系统默认的初始值undefiend)在代码解释期间这些值会相应被修改:
Active object(test)={
a:10,//函数的形参
b:undefined,//函数的另一个形参
c:10,//变量声明
d :<reference to Function Declaration>,//函数声明
e :<reference to FUNctionExpression “ee”>;,//变量声明
};
二.变量对象(variable object):因为变量与执行上下文相关,因此变量自己应该知道它的数据存储在哪里,并且知道如何访问,这种机制称为变量对象.
var a=10; function test(x){ var b=20; }; test(30);
对应的变量对象是:
//全局上下文的变量对象
variable object(Global object)={
a:10,
test:<>
};
//test函数上下文的变量对象
variable object(test) ={x:30,
b:20
};
全局对象(Global object)是在进入任何执行上下文之前就已经创建了的对象;这个对象只有一份,它的属性在程序中任何地方都可以访问,全局对象的生命周期终止于程序退出那一刻。
活动对象(Active object)是进入函数上下文时刻被创建的,它通过函数的arguments属性初始化。
在函数执行上下文中,VO是不能直接访问的,此时由活动对象(activation object)扮演VO的角色,活动上下文是在进入函数上下文时刻被创建的
三.总结:
一个执行上下文的数据(变量,函数声明,函数参数)存储在一个变量对象里,变量对象在每次进入执行上下文被创建,并带有默认的初始值,随之进入代码执行阶段,这些值会被更新。这些基本概念对作用域,闭包等等一些概念奠定了基础。
转载于:https://blog.51cto.com/xiyin001/1752423