var a=1;function b(x){ var c=2; console.log(x);}b(3);
·执行环境(execution context),也称为环境、执行上下文、上下文环境、执行上下文环境:
每次当控制器转到ECMAScript可执行代码的时候,即会进入到一个执行上下文。执行上下文(简称-EC)是ECMA-262标准里的一个抽象概念,用于同可执行代码(executable code,分为全局代码、函数代码和eval代码)概念进行区分。 通俗的话来讲就是,JS中的函数运行不能仅仅看函数内部有哪些变量,再简单的做运算就行了,而是执行前需要根据函数所处的环境(代码执行前的准备工作),如:变量、函数声明和arguments,来取值(在执行代码之前,把将要用到的所有的变量都事先拿出来,有的直接赋值了,有的先用undefined占个坑)运算。 执行环境主要包含变量对象、作用域链和this三部分内容。·变量对象(variable object):
变量对象属于执行环境的一部分,每个执行环境都有一个对象用来存储执行环境中的变量、函数声明和arguments,这个对象就是执行环境的变量对象。 全局环境的变量对象始终存在,局部环境变量对象只有在函数执行的过程中存在,每个函数都有自己的执行环境。 全局环境对象内容包括:var a=undefined、function b(){...}、this=windows。而像b()这样的的局部变量对象内容包括了:var c=undefined、arguments=[3]、x=3、this=windows。·活动对象(activation object): 在函数执行上下文中,VO是不能直接访问的,此时由活动对象(activation object,缩写为AO)扮演VO的角色。·作用域链:
function b(){}创建时,会创建一个预先包含全局变量的作用域链,这个作用域链被保存在[[Scope]]属性中。当b()调用时会创建一个执行环境,然后通过复制函数的[[Scope]]属性中对象构建起执行环境的作用域链。随后,又有一个活动对象(在此作为变量对象使用)被创建并推入执行环境作用域前端。对于这个例子中的执行环境而言,其作用域链包括了2个变量对象:全局变量对象和其内部活动对象。 显然,作用域链是本质上是一个指向变量对象的指针列表,它只是引用但不实际包含变量对象。·this:详情移动。
·执行上下文栈(execution context stack,ECS):
当我们运行多个函数时,如何管理那么多执行环境呢? 所以JS引擎创建了执行上下文栈来进行管理。当JS开始解释执行代码时,最先遇到的是全局代码,所以初始化时首先会向执行上下文栈中压入一个全局执行环境,并且只有当整个应用程序结束后,ECS才会被清空,全局执行环境在最底部是最后一个被清除的。·变量的搜索机制:
先搜索局部变量,如果没找到,往上一层查找,直到搜索全部变量,如果都没找到,返回undefined。