执行上下文(也称执行环境)
执行环境也成为执行上下文(Execution context,EC)。就是当js代码执行的时候,会进入不同的执行上下文,这些执行上下文就构成了一个执行上下文栈(Execution context stack,ECS)
- 全局执行环境:在浏览器环境中全局执行环境就是windows对象
- 函数执行环境:当某函数被调用时,首先会创建一个执行环境及相应的作用域链,然后使用
arguments
和其他命名参数的值来初始化执行环境的变量对象。
|
|
js代码运行时,首先进入Global Execution Context全局执行上下文,然后依次进入outer,inner,foo的执行上下文。执行上下文栈如下图。
- js代码执行的时候,第一个进入的总是Global Execution Context ,所以他总是在ECS的最底部。
- 函数的每次调用都会创建一个新的执行上下文。当执行流进入一个函数时,函数的环境就会被推入Execution Context Stack顶部。在函数执行完后,栈将其环境弹出,把控制权返回给之前的执行环境。
Execution Context
每个Execution Context都有3个重要的属性
变量对象(Variable object,VO):变量对象是与执行上下文相关的特殊的对象,存储了在上下文中定义的变量和函数声明。当js运行代码的时候如果要寻找变量,首选会查找VO。VO包含以下信息
- 变量
- 函数声明
- 函数的形参
作用域链(Scope chain):作用域即是变量对象,作用域链是一个由变量对象组成的带有头结点的单向链表,作用是用来进行有序地查找变量。内部环境可通过作用域链访问所有的外部环境,外部环境不能访问内部环境中的任何变量和函数。
[[Scope]]属性是一个指向单向链表的头结点的指针。
1当js代码进行变量查找时,首先从作用域链的第一个变量对象上查找,如果找不到就到第二个环境变量上查找,沿着作用域脸一级一级地搜索,最后到全局对象,如果在全局对象也找不到,就会抛出undefined的错误this:指向一个环境对象
活动对象(Activation object,AO)
- 在global全局上下文中,变量对象也是全局对象自身。
- 在函数上下文中,VO是不能直接访问的,则将其活动对象(activation object)作为变量对象。活动对象是在进入函数上下文的时候被创建的,它通过函数的arguments属性初始化
Arguments Objects 是函数上下文里的活动对象AO中的内部对象,它包括下列属性:
- callee:指向当前函数的引用
- length: 真正传递的参数的个数
- properties-indexes:就是函数的参数值(按参数列表从左到右排列)
当上面代码outer()执行的时候,就有一个outer的AO被创建
Activation object | |
---|---|
arguments 参数对象 | {} |
b 变量 | “var in outer” |
inner 函数声明 | \ |
Execution Context的内部过程
当js代码执行的时候,js解释器会创建Execution Context,这里有两个阶段
- 函数被调用,但是开始执行函数内部代码之前
- 创建VO/AO
- 根据函数的参数,创建并初始化参数对象arguments object
- 扫描内部代码,查找函数声明,并将函数名和函数引用存入VO/AO中
- 扫描内部代码,查找变量声明,并把变量名存入VO/AO中,并初始化为undefined
- 创建Scope chain,作用域链
- 确定this指向
- 创建VO/AO
- 函数内部代码执行阶段
- 设置变量的值,函数的引用,然后执行代码
执行环境的生命周期
作用域(Scope)
作用域分为全局作用域和局部作用域
- 全局作用域:
- 最外层函数及在最外层函数外定义的变量
- 没有通过关键字生命的变量
- 浏览器中,window对象的属性
|
|
|
|