在我们了解作用域链之前我们需要知道这几个概念:
函数的生命周期
变量和函数声明
Activetion Object (AO) , Variable Obect (VO)
函数的生命周期
创建阶段: js解析引擎会先进行预解析,会将函数声明提前,同时将函数放到全局作用域中 或者 当前函数的上一级函数作用域中.
执行阶段: js引擎会将当前函数的局部变量和内部函数进行声明提前,然后在执行业务代码,当函数执行完退出时,释放该函数的执行上下文,并注销该函数的局部变量.
变量和函数的声明提前
如果变量名和函数声明时相同,函数优先声明
Activetion Object(AO) , Variable Object(VO)
AO:活动对象
VO:变量对象
VO对应的是函数的创建阶段,js解析引擎进行预解析时,所有的变量和函数的生命,统称为VO 该变量与执行上下文相关,知道自己的数据储存在哪里,并且知道如何访问. VO是一个与执行上下文相关的特殊对象,他存储着在上下文中声明的以下内容:
* 变量 (var,变量声明);
* 函数声明(FunctionDeclaration);
* 函数的形参
AO对应的是函数的执行阶段,当函数被掉用时,会建立一个执行上下文,该执行上下文包含了函数所需的所有变量,该变量共同组成了一个新的对象就是Activetion Object.该对象包含了一下内容:
* 函数的所有局部变量;
* 函数的所有命名参数;
* 函数的参数集合;
* 函数的this指向;
作用域链:
好了大概了解了一下基本内容后我们开始理解一下作用域链;
当代码在一个环境中创建时,会创建变量对象的一个作用域链 (scope chain) 来保证对执行环境有效访问的变量和函数,作用域第一个对象始终是当前执行代码所在环境的变量对象(AO). 如果是函数执行阶段,那么将其(AO)作为作用域链第一个对象,第二个对象是上级函数的执行上下文AO,下一个对象依次类推.
然后当我们查找变量的时候,会先从当前的上下文的变量对象中查找,如果没有找到,就会从父级的执行上下文的变量对象中查找,一直找到全局的上下文的变量对象,也就是全局对象.这样由多个执行上下文的变量对象构成的链表就叫做作用域链.